Pandas绘图:每隔N个索引显示数据且必含最后一个索引
Pandas折线图标注:间隔显示且包含最后一个数据点
问题场景
用Pandas绘制折线图时,希望每隔固定间隔(比如2年)显示数据标注以保持图表简洁,但当前用df[['Year','Total value']][::3]选取的标注点会漏掉最后一个数据点,需要调整代码解决这个问题。
示例数据:
import pandas as pd df = pd.DataFrame({ 'Year': [2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021], 'Total value': [11.393630, 11.379185, 10.722502, 10.304044, 9.563496, 9.048299, 9.290901, 9.470320, 9.533228, 9.593088, 9.610742] })
现有代码(存在遗漏最后一个点的问题):
import matplotlib.pyplot as plt df.plot(x='Year') col_tuple = df[['Year','Total value']][::3] for j,k in col_tuple : plt.text(j,k*1.1,'%.2f'%(k)) plt.show()
修复方案
方法1:合并间隔选取数据与最后一行
直接将间隔筛选的数据集和最后一行数据合并,同时去重避免重复标注:
import matplotlib.pyplot as plt df.plot(x='Year') # 每隔3个索引选一个点,再拼接最后一行 annotate_data = pd.concat([df[['Year','Total value']][::3], df[['Year','Total value']].tail(1)]) # 去重,防止最后一行刚好是间隔选中的点 annotate_data = annotate_data.drop_duplicates() # 遍历每一行添加标注(注意原代码的遍历方式错误,应该用iterrows) for _, row in annotate_data.iterrows(): plt.text(row['Year'], row['Total value'] * 1.1, '%.2f' % row['Total value']) plt.show()
方法2:手动构建标注索引列表
先生成间隔索引,再检查最后一个索引是否在列表中,不在则添加:
import matplotlib.pyplot as plt df.plot(x='Year') step = 3 # 调整这个值改变间隔 # 生成间隔索引 annotate_indices = list(range(0, len(df), step)) # 确保最后一个数据点的索引被包含 if annotate_indices[-1] != len(df) - 1: annotate_indices.append(len(df) - 1) # 根据索引选取标注数据 annotate_data = df.loc[annotate_indices, ['Year', 'Total value']] for _, row in annotate_data.iterrows(): plt.text(row['Year'], row['Total value'] * 1.1, '%.2f' % row['Total value']) plt.show()
额外提示
- 原代码中
for j,k in col_tuple的遍历方式错误,因为DataFrame直接遍历会拿到列名而非行数据,必须用iterrows()来遍历每一行。 - 如果需要严格按年份间隔2年筛选(比如2011、2013、2015...2021),可以按年份列来筛选:
# 筛选奇数年(间隔2年),再拼接最后一行去重 year_mask = df['Year'] % 2 == 1 annotate_data = pd.concat([df[year_mask], df.tail(1)]).drop_duplicates()
内容的提问来源于stack exchange,提问作者Mainland
相关产品推荐
相关产品推荐

