Matplotlib子图日期时间X轴刻度无法正常工作 [英] Matplotlib Subplot Datetime X-Axis Ticks Not Working As Intended

查看:206
本文介绍了Matplotlib子图日期时间X轴刻度无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试绘制许多图,以下是数据的组织方式示例:

I'm attempting to plot many plots, here's a sample of how the data is organized:

我的意图是使用Google Analytics(分析)数据建立连续数小时或数天(例如一周7天,或一天24小时)的一系列子图。我的索引是日期时间对象。

My intention is to build a series of subplots for either hours or days (say 7 days in a week, or 24 hours in a day) using google analytics data. My index are date-time objects.

下面是一个示例,显示了正确完成轴操作后单个图的外观。

Here's an example of how a single plot looks, when the axis is done correctly.

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()

如您所见,x轴看起来不错,可以按预期使用正确的刻度/日期标签。

As you can see, the x axis looks good, working as intended with the right ticks/date labels.

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

However, when I try and run the same plot on a subplot series, I'm running into the following error. Here's my code:

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

但是,这会产生以下带有轴标记错误的非常时髦的图:

However, that yields the very funky plot below, with mislabelled axes:

我尝试添加另一行以查看其是否由于垂直空间而被覆盖:

I experimented with adding an additional row to see if it was just covering up because of vertical space:

,但是遇到相同的行为,只有最后一个子图的轴似乎在起作用,其余的轴却不起作用。

but was confronted with the same behavior, only the last subplot's axes appears to be working with the rest not working.

任何见识将不胜感激!

推荐答案

所以答案是在几年前提出的与 set_major_locator() set_major_formatter()对象有关的github问题中:

so the answer is in the following github issue raised a few years ago related to the set_major_locator() and set_major_formatter() objects:

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

引用eric:

您丢失了某些内容,但这是非常不直观且容易错过的事情:定位器无法在轴之间共享。set_major_locator()方法将其轴分配给该定位器,从而覆盖先前分配的任何轴。

"You are missing something, but it is something that is quite non-intuitive and easy to miss: Locators can't be shared among axes. The set_major_locator() method assigns its axis to that Locator, overwriting any axis that was previously assigned."

所以解决方案是实例化一个新的 dates.MinuteLocator dates.DateFormatter 每个新轴的对象,例如:

so the solution is to instantiate a new dates.MinuteLocator and dates.DateFormatter object for each new axes, e.g:

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_)

我已经尝试过了,看起来您不需要在绘图后引用date.Locator和date.Formatter对象,所以可以重新-使用相同的名称实例化每个循环。 (我可能在这里错了!)

I've experimented and it looks like you don't need to reference the dates.Locator and dates.Formatter objects after the plot so it's ok to just re-instantiate with each loop using the same name. (I could be wrong here though!)

这篇关于Matplotlib子图日期时间X轴刻度无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆