尽管付出了最大的努力,Matplotlib显示x-tick标签重叠

8on*_*ne6 34 python matplotlib pandas

看看下面的图表: 在此输入图像描述

这是这个更大的数字的子情节: 在此输入图像描述

我看到它有两个问题.首先,x轴标签相互重叠(这是我的主要问题).第二.x轴次网格线的位置似乎有点不稳定.在图表的左侧,它们看起来间隔适当.但在右边,它们似乎挤满了主要的网格线......好像主要的网格线位置不是小刻度线位置的正确倍数.

我的设置是我有一个DataFrame df,它有一个DatetimeIndex行和一个value包含浮点数的列.df如有必要,我可以在要点中提供内容的示例.df这篇文章的底部有十几行作为参考.

这是生成图形的代码:

now = dt.datetime.now()

fig, axes = plt.subplots(2, 2, figsize=(15, 8), dpi=200)
for i, d in enumerate([360, 30, 7, 1]):
    ax = axes.flatten()[i]
    earlycut = now - relativedelta(days=d)
    data = df.loc[df.index>=earlycut, :]
    ax.plot(data.index, data['value'])
    ax.xaxis_date()

    ax.get_xaxis().set_minor_locator(mpl.ticker.AutoMinorLocator())
    ax.get_yaxis().set_minor_locator(mpl.ticker.AutoMinorLocator())

    ax.grid(b=True, which='major', color='w', linewidth=1.5)
    ax.grid(b=True, which='minor', color='w', linewidth=0.75)
Run Code Online (Sandbox Code Playgroud)

这里我最好的选择是让x轴标签相互重叠(在四个子图中的每一个中)?另外,单独(但不太紧急),左上方子图中的次要刻度问题是什么?

我在Pandas 0.13.1,numpy 1.8.0和matplotlib 1.4.x.

这里有一小段df供参考:

                                    id scale  tempseries_id    value
timestamp                                                           
2014-11-02 14:45:10.302204+00:00  7564     F              1  68.0000
2014-11-02 14:25:13.532391+00:00  7563     F              1  68.5616
2014-11-02 14:15:12.102229+00:00  7562     F              1  68.9000
2014-11-02 14:05:13.252371+00:00  7561     F              1  69.0116
2014-11-02 13:55:11.792191+00:00  7560     F              1  68.7866
2014-11-02 13:45:10.782227+00:00  7559     F              1  68.6750
2014-11-02 13:35:10.972248+00:00  7558     F              1  68.4500
2014-11-02 13:25:10.362213+00:00  7557     F              1  68.1116
2014-11-02 13:15:10.822247+00:00  7556     F              1  68.2250
2014-11-02 13:05:10.102200+00:00  7555     F              1  68.5616
2014-11-02 12:55:10.292217+00:00  7554     F              1  69.0116
2014-11-02 12:45:10.382226+00:00  7553     F              1  69.3500
2014-11-02 12:35:10.642245+00:00  7552     F              1  69.2366
2014-11-02 12:25:12.642255+00:00  7551     F              1  69.1250
2014-11-02 12:15:11.122382+00:00  7550     F              1  68.7866
2014-11-02 12:05:11.332224+00:00  7549     F              1  68.5616
2014-11-02 11:55:11.662311+00:00  7548     F              1  68.2250
2014-11-02 11:45:11.122193+00:00  7547     F              1  68.4500
2014-11-02 11:35:11.162271+00:00  7546     F              1  68.7866
2014-11-02 11:25:12.102211+00:00  7545     F              1  69.2366
2014-11-02 11:15:10.422226+00:00  7544     F              1  69.4616
2014-11-02 11:05:11.412216+00:00  7543     F              1  69.3500
2014-11-02 10:55:10.772212+00:00  7542     F              1  69.1250
2014-11-02 10:45:11.332220+00:00  7541     F              1  68.7866
2014-11-02 10:35:11.332232+00:00  7540     F              1  68.5616
2014-11-02 10:25:11.202411+00:00  7539     F              1  68.2250
2014-11-02 10:15:11.932326+00:00  7538     F              1  68.5616
2014-11-02 10:05:10.922229+00:00  7537     F              1  68.9000
2014-11-02 09:55:11.602357+00:00  7536     F              1  69.3500
Run Code Online (Sandbox Code Playgroud)

编辑:尝试fig.autofmt_xdate():我不认为这会成功.这似乎对左侧的两个图形和右侧的两个图形使用相同的x-tick标签.根据我的数据,这是不正确的.请查看下面有问题的输出:

在此输入图像描述

8on*_*ne6 25

好的,终于搞定了.诀窍是用于plt.setp手动旋转刻度标签.使用fig.autofmt_xdate()不起作用,因为当你的图中有多个子图时它会发生一些意想不到的事情.这是工作代码及其输出:

for i, d in enumerate([360, 30, 7, 1]):
    ax = axes.flatten()[i]
    earlycut = now - relativedelta(days=d)
    data = df.loc[df.index>=earlycut, :]
    ax.plot(data.index, data['value'])

    ax.get_xaxis().set_minor_locator(mpl.ticker.AutoMinorLocator())
    ax.get_yaxis().set_minor_locator(mpl.ticker.AutoMinorLocator())

    ax.grid(b=True, which='major', color='w', linewidth=1.5)
    ax.grid(b=True, which='minor', color='w', linewidth=0.75)

    plt.setp(ax.get_xticklabels(), rotation=30, horizontalalignment='right')

fig.tight_layout()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

顺便说一句,早些时候关于一些matplotlib事情的评论在这里非常有趣.我正在使用覆盆子pi作为远程位置的气象站.它正在收集数据并通过网络提供结果.而且男孩哦,男孩,这真的喘息着试图推出这些图形.

  • 对我来说,我需要的是`plt.setp(ax.get_xticklabels(),rotation=30,horizo​​ntalalignment='right',fontsize='x-small')`。顺便说一句,干得好。谢谢! (6认同)

Joe*_*ton 12

由于在matplotlib中处理文本渲染的方式,自动检测重叠文本确实减慢了速度.(文本占用的空间在绘制之前无法准确计算.)因此,matplotlib不会尝试自动执行此操作.

因此,最好旋转长刻度标签.因为日期最常出现这个问题,所以有一种数字方法fig.autofmt_xdate()可以(除其他外)旋转刻度标签以使它们更具可读性.(注意:如果你使用的是pandas plot方法,它会返回一个axis对象,所以你需要使用它ax.figure.autofmt_xdate().)

作为一个简单的例子:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

time = pd.date_range('01/01/2014', '4/01/2014', freq='H')
values = np.random.normal(0, 1, time.size).cumsum()

fig, ax = plt.subplots()
ax.plot_date(time, values, marker='', linestyle='-')

fig.autofmt_xdate()
plt.show()
Run Code Online (Sandbox Code Playgroud)

如果我们遗漏fig.autofmt_xdate():

在此输入图像描述

如果我们使用fig.autofmt_xdate():

在此输入图像描述