如何在基于月度刻度的水平条形图子图Y轴显示年份且不修改绘图数据
如何在基于月度刻度的水平条形图子图Y轴显示年份且不修改绘图数据
我完全理解你的困扰——你有按月度统计的堆叠水平条形图,Y轴现在挤满了2006到2023的每个月份标签,看起来杂乱不堪,你想把Y轴简化为只显示年份,但又不想改变背后的月度统计数据,对吧?
下面是针对你代码的修改方案,核心思路是替换Y轴的刻度标签,仅在每年的起始位置显示年份,其余月份留空,同时可添加年份分隔线增强视觉分组效果:
修改后的完整代码
import pandas as pd import matplotlib.pyplot as plt import matplotlib.dates as mdates df = pd.read_csv('NYPD_Arrests_Data__Historic__20250113_111.csv') df['ARREST_DATE'] = pd.to_datetime(df['ARREST_DATE'], format = '%m/%d/%Y') df['ARREST_MONTH'] = df['ARREST_DATE'].dt.to_period('M').dt.to_timestamp() # crimes, attributes and renames crimes = ['DANGEROUS DRUGS', 'DANGEROUS WEAPONS', 'ASSAULT 3 & RELATED OFFENSES', 'FELONY ASSAULT'] attributes = ['PERP_RACE'] titles = ['Race'] # loops plot creation over each attribute for attr, title in zip(attributes, titles): fig, axes = plt.subplots(1, len(crimes), figsize = (4 * len(crimes), 6), sharey = 'row') for i, crime in enumerate(crimes): ax = axes[i] crime_df = df[df['OFNS_DESC'] == crime] pivot = pd.crosstab(crime_df['ARREST_MONTH'], crime_df[attr]) # 绘制堆叠水平条形图 pivot.plot(kind = 'barh', stacked = True, ax = ax, width = 0.9, legend = False) # ------------ 重点:修改Y轴刻度标签为年份 ------------ # 获取所有月度时间戳 months = pivot.index ytick_labels = [] prev_year = None # 遍历每个月份,仅在每年第一个月显示年份,其余留空 for month in months: current_year = month.year if current_year != prev_year: ytick_labels.append(str(current_year)) prev_year = current_year else: ytick_labels.append('') # 设置Y轴标签 ax.set_yticklabels(ytick_labels) # 可选:添加年份分隔线,增强视觉分组效果 for year in months.year.unique(): # 找到该年最后一个月的索引位置 year_months = months[months.year == year] last_month_pos = pivot.index.get_loc(year_months[-1]) # 在该年最后一个条形的上方添加灰色虚线 ax.axhline(y=last_month_pos + 0.5, color='#cccccc', linestyle='--', linewidth=0.8) # ------------ 原有绘图设置保留 ------------ ax.set_title(crime) ax.set_xlabel('Frequency') ax.set_ylabel('Year' if i == 0 else '') # 把Y轴标题改成Year更准确 ax.xaxis.set_tick_params(labelsize = 8) # 公共图例设置 handles, labels = ax.get_legend_handles_labels() fig.legend(handles, labels, title = title, loc = 'upper center', ncol = len(df[attr].unique()), bbox_to_anchor = (0.5, 0.94)) fig.suptitle(f'Crime Frequency Distribution by Year and {title}', fontsize = 20) plt.tight_layout(rect = [0, 0, 1, 0.90]) plt.show()
关键修改说明
- Y轴标签替换:遍历每个月度索引,仅在每年的第一个月对应的位置显示年份,其他月份的标签设为空字符串——既保留了每个月度条形的原始位置(数据完全不变),又让Y轴简洁易读。
- 年份分隔线(可选):在每年最后一个月度条形的上方添加灰色虚线,帮助读者快速区分不同年份的分组,让图表层次更清晰。
- Y轴标题调整:把原来的
Month改成Year,更符合现在的Y轴显示内容。
这样修改后,你的图表Y轴就会只显示2006、2007...2023这些年份标签,而背后的每个月度统计条形依然完整保留,完美解决了你的需求~
内容来源于stack exchange
相关产品推荐
相关产品推荐

