如何用Pandas/Matplotlib实现月度网格且始于01_01的湖水位折线图
问题解决:复刻湖泊水位长期极值与均值折线图
问题背景
我希望使用Pandas/Matplotlib复刻某折线图,该图展示了某湖泊水位的长期最大值、最小值及平均值,所有数据点基于月日(MM_dd)信息。
现有数据
拥有DataFrame df_lt_1981,包含以下字段:
mm_dd:存储月日信息(例如'02-03'代表2月3日)month:存储月份信息(例如'01'代表1月)value_min:存储当日的长期最小值(例如241)value_mean:存储当日的长期平均值(例如296.658537)value_max:存储当日的长期最大值(例如360)
现有代码
import matplotlib.pyplot as plt # Set the figure size plt.figure(figsize=(10, 6)) # Plot df_lt_1981.plot(x='month', kind='line') # add grid plt.grid() # Set axis limits plt.ylim(0, 800) # Set labels and title plt.xlabel('month') plt.ylabel('Values') plt.title('Comparing min, mean, and max based on data starting in 1981') # Add legend plt.legend() # Show the plot plt.show()
待解决问题
生成的图表已接近目标,但仍需解决两个问题:
- 设置按月划分的网格
- 让图表从01-01开始,而非更早的日期
解决方案
1. 确保图表从01-01开始
先对DataFrame按mm_dd排序,再筛选出从'01-01'开始的记录:
import pandas as pd # 按mm_dd字段从小到大排序 df_lt_1981 = df_lt_1981.sort_values('mm_dd') # 筛选仅保留01-01及之后的记录 df_filtered = df_lt_1981[df_lt_1981['mm_dd'] >= '01-01']
2. 设置按月划分的网格
将mm_dd转换为datetime类型,让Matplotlib自动识别月份刻度,进而实现按月网格:
import matplotlib.pyplot as plt import matplotlib.dates as mdates # 将mm_dd转为datetime格式(用任意不影响月日的年份,这里选2020) df_filtered['date'] = pd.to_datetime('2020-' + df_filtered['mm_dd']) # 创建画布 plt.figure(figsize=(10, 6)) # 分别绘制三条折线 plt.plot(df_filtered['date'], df_filtered['value_min'], label='长期最小值') plt.plot(df_filtered['date'], df_filtered['value_mean'], label='长期平均值') plt.plot(df_filtered['date'], df_filtered['value_max'], label='长期最大值') # 设置x轴主刻度为每月,显示月份缩写(如Jan、Feb) ax = plt.gca() ax.xaxis.set_major_locator(mdates.MonthLocator()) ax.xaxis.set_major_formatter(mdates.DateFormatter('%b')) # 设置按月划分的网格(x轴主网格对应月份刻度) plt.grid(axis='x', which='major', linestyle='-', linewidth=0.7) plt.grid(axis='y', linestyle='--', linewidth=0.5) # 设置轴标签与标题 plt.xlabel('日期') plt.ylabel('水位值') plt.title('1981年起湖泊水位长期极值与均值对比') # 添加图例 plt.legend() # 设置y轴范围 plt.ylim(0, 800) # 展示图表 plt.show()
关键说明
- 转换为datetime类型后,Matplotlib能精准识别月份间隔,无需手动计算刻度位置,大幅简化网格设置。
- 排序+筛选操作确保图表从'01-01'开始,避免出现跨年的早于1月1日的记录。
- 若不想新增
date列,也可通过mm_dd的索引位置手动设置刻度,但datetime方法更直观可靠。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

