Matplotlib Subplot日期时间X轴刻度不按预期工作

mbu*_*e05 2 python plot datetime matplotlib

我试图绘制许多图,这里是一个如何组织数据的示例:

数据帧

我的目的是使用谷歌分析数据建立一系列的小时或几天(比如一周7天,或一天24小时)的子图.我的索引是日期时间对象.

下面是一个示例,说明当轴正确完成时单个绘图的外观.

from datetime import datetime, date, timedelta
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
import matplotlib.dates as dates

#creating our graph and declaring our locator/formatters used in axis labelling.
hours = dates.HourLocator(interval=2)
hours_ = dates.DateFormatter('%I %p')

el = datetime(year=2016, day=1, month=3, hour=0)
fig, ax = plt.subplots(ncols = 1, nrows= 1)
fig.set_size_inches(18.5, 10.5)
fig.tight_layout()
ax.set_title(el.strftime('%a, %m/%d/%y'))
ax.plot(df_total.loc[el:el+timedelta(hours=23, minutes=59),:].index, 
                             df_total.loc[el:el+timedelta(hours=23, minutes=59),:].hits, '-')
ax.xaxis.set_major_locator(hours)
ax.xaxis.set_major_formatter(hours_) 
fig.show()
Run Code Online (Sandbox Code Playgroud)

右图!

正如您所看到的,x轴看起来很好,正常工作时使用正确的刻度/日期标签.

但是,当我尝试在子图系列上运行相同的图时,我遇到了以下错误.这是我的代码:

fig, ax = plt.subplots(ncols = 3, nrows= 2)
fig.set_size_inches(18.5, 10.5)
fig.tight_layout()

nrows=2
ncols=3

count = 0

for row in range(nrows):
    for column in range(ncols):
        el = cleaned_date_range[count]
        ax[row][column].set_title(el.strftime('%a, %m/%d/%y'))
        ax[row][column].xaxis.set_major_locator(hours)
        ax[row][column].xaxis.set_major_formatter(hours_)
        ax[row][column].plot(df_total.loc[el:el+timedelta(hours=23,minutes=59),:].index, df_total.loc[el:el+timedelta(hours=23,minutes=59),:].hits)
        count += 1

        if count == 7:
            break
Run Code Online (Sandbox Code Playgroud)

然而,这会产生下面非常时髦的情节,标签错误标记:

错图!

我尝试添加一行来查看它是否因为垂直空间而被覆盖: 在此输入图像描述

但是面对同样的行为,只有最后一个子情节的轴似乎正在与其余部分不起作用.

任何见解将不胜感激!

mbu*_*e05 5

所以答案是以下GitHub的问题提出了数年前相关set_major_locator()set_major_formatter()对象:

https://github.com/matplotlib/matplotlib/issues/1086/

引用埃里克:

"你失去了一些东西,但它的东西是非常不直观和容易错过:定位器无法轴之间共享的set_major_locator()方法,它的轴分配给该定位器,覆盖先前指定的任何轴. "

因此该解决方案是实例化新的dates.MinuteLocatordates.DateFormatter对象为每个新的轴,例如:

for ax in list_of_axes:
    minutes = dates.MinuteLocator(interval=5)
    minutes_ = dates.DateFormatter('%I:%M %p')
    ax.xaxis.set_major_locator(minutes)
    ax.xaxis.set_major_formatter(minutes_)
Run Code Online (Sandbox Code Playgroud)

我已经进行了实验,看起来你不需要在绘图之后引用dates.Locator和dates.Formatter对象,所以可以使用相同的名称重新实例化每个循环.(虽然我在这里错了!)