如何设置Pandas绘图中X轴刻度的自定义显示顺序?
问题描述
现有DataFrame如下:
USER_ID EventNum 0 1390 17 1 4452 15 2 995 14 3 532 14 4 3281 14 ... ... ... 5897 4971 1 5898 2637 1 5899 792 1 5900 5622 1 5901 1 1 [5902 rows x 2 columns]
需要绘制以USER_ID为X轴、EventNum为Y轴的图表,为避免X轴标签拥挤,采样了一组固定顺序的USER_ID作为刻度:
[1390, 4899, 4062, 366, 5001, 3383, 5003, 446, 2879, 3220, 4006, 4595, 1713, 2649, 2291, 5647, 2040, 5468, 3719, 4198, 5622]
编写的代码如下,但X轴刻度始终按数值升序排列,而非指定顺序:
xticks = [1390, 4899, 4062, 366, 5001, 3383, 5003, 446, 2879, 3220, 4006, 4595, 1713, 2649, 2291, 5647, 2040, 5468, 3719, 4198, 5622] ax = df.plot(x='USER_ID', y=['EventNum'], use_index=False, rot=270) ax.set_xticks(xticks) ax.set_xlabel('User ID') ax.set_ylabel('Event Number')
(图表显示X轴刻度按数值排序)
解决方案
问题核心:当USER_ID为数值型时,matplotlib会默认按数值大小对X轴排序,set_xticks仅指定显示的刻度值,无法改变轴的排序逻辑。以下是三种可行解决方法:
方法一:将USER_ID转为字符串类型
把数值型USER_ID转为字符串,让matplotlib将其视为分类变量,保留原始顺序:
xticks = [1390, 4899, 4062, 366, 5001, 3383, 5003, 446, 2879, 3220, 4006, 4595, 1713, 2649, 2291, 5647, 2040, 5468, 3719, 4198, 5622] # 转换USER_ID为字符串类型 df['USER_ID'] = df['USER_ID'].astype(str) # 获取目标刻度对应的行索引 tick_indices = df[df['USER_ID'].isin([str(x) for x in xticks])].index ax = df.plot(x='USER_ID', y=['EventNum'], use_index=False, rot=270) ax.set_xticks(tick_indices) ax.set_xticklabels(xticks) ax.set_xlabel('User ID') ax.set_ylabel('Event Number')
方法二:使用matplotlib原生绘图
跳过pandas的plot方法,手动控制数据顺序和刻度:
import matplotlib.pyplot as plt xticks = [1390, 4899, 4062, 366, 5001, 3383, 5003, 446, 2879, 3220, 4006, 4595, 1713, 2649, 2291, 5647, 2040, 5468, 3719, 4198, 5622] # 按指定顺序筛选并重新排列数据 filtered_df = df[df['USER_ID'].isin(xticks)].set_index('USER_ID').reindex(xticks) plt.figure(figsize=(12,6)) plt.plot(filtered_df.index, filtered_df['EventNum']) plt.xticks(xticks, rotation=270) plt.xlabel('User ID') plt.ylabel('Event Number') plt.show()
方法三:设置X轴为分类轴(matplotlib 3.1+)
强制将X轴设为分类类型,保留原始顺序:
xticks = [1390, 4899, 4062, 366, 5001, 3383, 5003, 446, 2879, 3220, 4006, 4595, 1713, 2649, 2291, 5647, 2040, 5468, 3719, 4198, 5622] ax = df.plot(x='USER_ID', y=['EventNum'], use_index=False, rot=270) # 设置X轴为分类类型 ax.xaxis.set_type('category') # 指定刻度位置和标签 ax.set_xticks([df[df['USER_ID'] == x].index[0] for x in xticks]) ax.set_xticklabels(xticks) ax.set_xlabel('User ID') ax.set_ylabel('Event Number')
内容的提问来源于stack exchange,提问作者l4rmbr
相关产品推荐
相关产品推荐

