如何用Matplotlib基于Pandas DataFrame绘制各类别计数随年月变化折线图
绘制多分类时间序列折线图的实现方案
嘿,这个需求很常见,我给你两种靠谱的实现方式,你可以根据自己的需求选择:
方法一:用透视表快速生成(简洁高效)
这种方法适合不需要个性化调整单条折线的场景,代码量少,逻辑清晰:
步骤拆解
- 转换时间格式:先把
year-month字符串转成datetime类型,确保时间轴的顺序是正确的(避免出现2016-12排在2017-01前面的情况)。 - 透视数据:将数据整理成「时间为行,分类为列」的格式,这样Pandas可以直接帮我们生成多条折线。
- 绘图并美化:添加标题、坐标轴标签、图例,调整布局让图表更易读。
完整代码
import pandas as pd import matplotlib.pyplot as plt # 模拟你的DataFrame(你可以替换成自己的真实数据) data = { 'year-month': ['2016-01', '2016-02', '2016-01', '2016-02', '2016-03', '2016-03'], 'cat': [1, 1, 2, 2, 1, 2], 'count': [14, 22, 10, 18, 25, 15] } df = pd.DataFrame(data) # 1. 转换时间列格式 df['year-month'] = pd.to_datetime(df['year-month'], format='%Y-%m') # 2. 透视数据:行=时间,列=分类,值=count pivot_df = df.pivot(index='year-month', columns='cat', values='count') # 3. 绘制折线图 plt.figure(figsize=(12, 6)) # 设置画布大小 pivot_df.plot(ax=plt.gca()) # 在当前轴上绘制所有分类的折线 # 添加图表美化元素 plt.title('Count Trend by Category Over 8 Years', fontsize=14) plt.xlabel('Year-Month', fontsize=12) plt.ylabel('Count', fontsize=12) # 把图例放在画布外侧,避免遮挡折线 plt.legend(title='Category', bbox_to_anchor=(1.05, 1), loc='upper left') plt.xticks(rotation=45) # 旋转x轴标签,防止重叠 plt.tight_layout() # 自动调整布局,确保所有元素都显示完整 plt.show()
方法二:循环遍历分类(灵活自定义)
如果需要给每个分类的折线设置不同的颜色、线型,或者单独处理某些分类的数据,这种循环方法会更灵活:
完整代码
import pandas as pd import matplotlib.pyplot as plt # 同样先准备数据(替换成你的真实数据) data = { 'year-month': ['2016-01', '2016-02', '2016-01', '2016-02', '2016-03', '2016-03'], 'cat': [1, 1, 2, 2, 1, 2], 'count': [14, 22, 10, 18, 25, 15] } df = pd.DataFrame(data) # 转换时间列格式 df['year-month'] = pd.to_datetime(df['year-month'], format='%Y-%m') # 创建画布 plt.figure(figsize=(12, 6)) # 遍历每个唯一的分类,单独绘制折线 for cat in df['cat'].unique(): # 筛选当前分类的数据,并按时间排序 subset = df[df['cat'] == cat].sort_values('year-month') # 绘制折线,可以自定义颜色、线型等参数 plt.plot(subset['year-month'], subset['count'], label=f'Category {cat}', linewidth=2) # 添加图表美化元素 plt.title('Count Trend by Category Over 8 Years', fontsize=14) plt.xlabel('Year-Month', fontsize=12) plt.ylabel('Count', fontsize=12) plt.legend(title='Category', bbox_to_anchor=(1.05, 1), loc='upper left') plt.xticks(rotation=45) plt.tight_layout() plt.show()
注意事项
- 如果某些分类在部分月份没有数据,透视后会出现
NaN,可以用pivot_df.fillna(0)填充为0,或者pivot_df.dropna()删除缺失值(根据你的业务需求选择)。 - 因为你的数据跨度8年,x轴标签会比较多,
rotation=45和tight_layout能有效避免标签重叠问题。
内容的提问来源于stack exchange,提问作者pfnuesel




