如何去除Matplotlib柱状图间距及数据缺失导致的多余连线?
解决柱状图间距与折线图多余连线问题
问题根源
- 柱状图:
date_all是不连续的日期,matplotlib会按实际日期的时间间隔绘制柱子,缺失月份的位置就会出现空白间距。 - 折线图:各折线的日期数组不连续,
plt.plot默认会把所有点按顺序强制连接,哪怕中间隔了多个月份,就出现了跨缺失段的多余连线。
具体解决步骤
1. 生成完整的日期基准序列
先构建2019-2021年的所有月份作为统一的x轴基准,确保每个月份都有对应位置:
import pandas as pd import numpy as np import matplotlib.pyplot as plt # 生成2019-01到2021-12的完整月份序列 full_dates = pd.date_range(start='2019-01', end='2021-12', freq='MS') # 转换成和现有日期格式一致的字符串(比如'YYYY-MM') full_dates_str = full_dates.strftime('%Y-%m')
2. 处理柱状图数据,消除间距
把现有柱状图数据对齐到完整日期序列,缺失月份的数值设为0,用序列索引作为x值绘制,保证柱子紧密排列:
# 初始化全0数组,对应每个完整月份 bar_values = np.zeros(len(full_dates_str)) # 匹配已有数据的位置并赋值 for date, val in zip(date_all, value_all): if date in full_dates_str: idx = np.where(full_dates_str == date)[0][0] bar_values[idx] = val # 用索引绘制柱状图,width=1确保无间距 plt.figure(figsize=(30,10)) plt.bar(range(len(full_dates_str)), bar_values, color='black', width=1)
3. 处理折线图数据,去掉多余连线
对每个折线的日期和数值,对齐到完整日期序列,缺失月份的数值设为NaN——matplotlib绘制时会自动跳过NaN,不会连接不连续的点:
def align_to_full_dates(date_list, value_list, full_dates): aligned_values = np.full(len(full_dates), np.nan) for date, val in zip(date_list, value_list): if date in full_dates: idx = np.where(full_dates == date)[0][0] aligned_values[idx] = val return aligned_values # 逐个处理各折线的数据 inflation_vals = align_to_full_dates(date_economic_inflation, value_economic_inflation, full_dates_str) cost_vals = align_to_full_dates(date_economic_cost_of_living, value_economic_cost_of_living, full_dates_str) income_vals = align_to_full_dates(date_economic_income, value_economic_income, full_dates_str) redundancy_vals = align_to_full_dates(date_economic_redundancy, value_economic_redundancy, full_dates_str) newcar_vals = align_to_full_dates(date_economic_new_car, value_economic_new_car, full_dates_str) policy_vals = align_to_full_dates(date_economic_policy_war, value_economic_policy_war, full_dates_str) # 绘制折线图,仅连接有数据的连续点 plt.plot(range(len(full_dates_str)), inflation_vals, color='r', label='Economic Inflation', marker='o') plt.plot(range(len(full_dates_str)), cost_vals, color='g', label='Cost of Living', marker='o') plt.plot(range(len(full_dates_str)), income_vals, color='b', label='Income Level', marker='o') plt.plot(range(len(full_dates_str)), redundancy_vals, color='c', label='Redundancy', marker='o') plt.plot(range(len(full_dates_str)), newcar_vals, color='m', label='New Car Type', marker='o') plt.plot(range(len(full_dates_str)), policy_vals, color='y', label='Influence of Policies & War', marker='o')
4. 设置x轴刻度,显示正确月份
把x轴刻度替换为对应的月份字符串,避免显示索引:
plt.xticks(range(len(full_dates_str)), full_dates_str, fontsize=20, rotation=45) plt.title('2019-2021年新冠疫情期间与购车相关的推文数量', fontsize=18) plt.legend(fontsize=12) plt.tight_layout() # 自动调整布局,避免刻度被截断 plt.show()
补充说明
- 如果你的日期格式不是
YYYY-MM,调整strftime的格式即可,确保和date_all等数组里的日期格式一致。 marker='o'是为了更清晰地标记有数据的点,不需要可以直接去掉。
内容的提问来源于stack exchange,提问作者Kaiye Yang
相关产品推荐
相关产品推荐

