隐藏 xticks 标签每第 n 个标签或 Pandas 绘图上的值/使 x 轴可读

Jea*_*tan 8 python matplotlib python-3.x pandas axis-labels

由于图片的原因,问题很长,但实际内容并不多。问题在最下面。

你好,我有一系列 30000 个年龄范围从 21 岁到 74 岁的样本。系列头:

0    24
1    26
2    34
3    37
4    57
Name: AGE, dtype: int64
Run Code Online (Sandbox Code Playgroud)

我使用内置的 Pandas 功能绘制它.plot

age_series = original_df['AGE']
fig = plt.figure()
fig.suptitle('Age distribution')
age_series.value_counts().sort_index().plot(kind='bar')
Run Code Online (Sandbox Code Playgroud)

我的问题是它使 x 轴不太用户友好: 原图

我可以增加条之间的水平宽度,但我不想这样做。相反,我只想使 x 轴标签的子集可见。我尝试使用MaxNLocatorMultipleLocator添加这一行:

plt.gca().xaxis.set_major_locator(plt.MaxNLocator(10))
Run Code Online (Sandbox Code Playgroud)

但是,它没有实现我的目标,因为它现在错误地标记了条形图并删除了刻度线(我理解这一点,因为使用这些函数会更改 xticks 对象): 最大N定位器(10)

一个丑陋的解决方案是在 xticks 对象内循环:

xticks = plt.gca().xaxis.get_major_ticks()
for i in range(len(xticks)):
    if i % 10 != 0:
        xticks[i].set_visible(False)
Run Code Online (Sandbox Code Playgroud)

允许此渲染,这接近我想要的: 在此输入图像描述

然而我不满意,因为循环太天真了。我希望能够访问 xticks(标签)中的值并对其做出决定,以便能够仅显示 10 个标签的倍数。

这有效(基于这个答案):

for i, l in enumerate(labels):
    val = int(l.get_text())
    if val % 10 != 0:
        labels[i] = ''
    plt.gca().set_xticklabels(labels)
Run Code Online (Sandbox Code Playgroud)

丑陋的解决方法

问题:是否有任何不同的解决方案,感觉更Pythonic/高效?或者您对如何使这些数据可读有什么建议吗?

Joe*_*Joe 6

我想你可以尝试这样的事情:

ax = plt.gca()
pos = [9,19,29,39,49]
l = [30,40,50,60,70]
ax.set(xticks=pos, xticklabels=l)
Run Code Online (Sandbox Code Playgroud)


小智 6

为了更通用,你可以这样做:

import numpy as np

ax = plt.gca()

max_value = original_df['AGE'].max()
min_value = original_df['AGE'].min()
number_of_steps = 5
l = np.arange(min_value, max_value+1, number_of_steps)

ax.set(xticks=l, xticklabels=l)
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,这就是我一直在寻找的,它比随机循环干净得多。但是,它需要对位置进行轻微调整:使用 `xticks=l` 将使刻度向右移动,因为我的起始数据点是 21。这是我添加的修复:`ax.set(xticks=[x - l] [0] 对于 l 中的 x,xticklabels=l)` (2认同)