簡體   English   中英

matplotlib 中的日期刻度和旋轉

[英]Date ticks and rotation in matplotlib

我在嘗試在 matplotlib 中旋轉我的日期刻度時遇到問題。 下面是一個小示例程序。 如果我嘗試在最后旋轉刻度,刻度不會旋轉。 如果我嘗試按照注釋“崩潰”下所示旋轉刻度,則 matplot lib 會崩潰。

僅當 x 值是日期時才會發生這種情況。 如果我取代了變量dates與變量t在調用avail_plotxticks(rotation=70)調用工作就好內avail_plot

有任何想法嗎?

import numpy as np
import matplotlib.pyplot as plt
import datetime as dt

def avail_plot(ax, x, y, label, lcolor):
    ax.plot(x,y,'b')
    ax.set_ylabel(label, rotation='horizontal', color=lcolor)
    ax.get_yaxis().set_ticks([])

    #crashes
    #plt.xticks(rotation=70)

    ax2 = ax.twinx()
    ax2.plot(x, [1 for a in y], 'b')
    ax2.get_yaxis().set_ticks([])
    ax2.set_ylabel('testing')

f, axs = plt.subplots(2, sharex=True, sharey=True)
t = np.arange(0.01, 5, 1)
s1 = np.exp(t)
start = dt.datetime.now()
dates=[]
for val in t:
    next_val = start + dt.timedelta(0,val)
    dates.append(next_val)
    start = next_val

avail_plot(axs[0], dates, s1, 'testing', 'green')
avail_plot(axs[1], dates, s1, 'testing2', 'red')
plt.subplots_adjust(hspace=0, bottom=0.3)
plt.yticks([0.5,],("",""))
#doesn't crash, but does not rotate the xticks
#plt.xticks(rotation=70)
plt.show()

如果您更喜歡非面向對象的方法,請將plt.xticks(rotation=70)移動到兩個avail_plot調用之前,例如

plt.xticks(rotation=70)
avail_plot(axs[0], dates, s1, 'testing', 'green')
avail_plot(axs[1], dates, s1, 'testing2', 'red')

這會在設置標簽之前設置旋轉屬性。 由於這里有兩個軸, plt.xticks在繪制兩個圖后plt.xticks會感到困惑。 而此時點plt.xticks不會做任何事情, plt.gca()給你,你要修改的軸,所以plt.xticks ,作用於當前坐標,是行不通的。

對於不使用plt.xticks的面向對象方法,您可以使用

plt.setp( axs[1].xaxis.get_majorticklabels(), rotation=70 )

兩次avail_plot調用之后。 這會專門設置正確軸上的旋轉。

解決方案適用於 matplotlib 2.1+

存在可以更改刻度屬性的軸方法tick_params 它也作為軸方法存在,如set_tick_params

ax.tick_params(axis='x', rotation=45)

或者

ax.xaxis.set_tick_params(rotation=45)

作為旁注,當前的解決方案通過使用命令plt.xticks(rotation=70)將有狀態接口(使用 pyplot)與面向對象的接口混合在一起。 由於問題中的代碼使用面向對象的方法,因此最好始終堅持該方法。 該解決方案確實使用plt.setp( axs[1].xaxis.get_majorticklabels(), rotation=70 )提供了一個很好的顯式解決方案

避免在刻度線上循環的一個簡單的解決方案是使用

fig.autofmt_xdate()

此命令會自動旋轉 xaxis 標簽並調整它們的位置。 默認值是旋轉角度 30° 和水平對齊“右”。 但是它們可以在函數調用中改變

fig.autofmt_xdate(bottom=0.2, rotation=30, ha='right')

額外的bottom參數等效於設置plt.subplots_adjust(bottom=bottom) ,它允許將底部軸填充設置為更大的值以承載旋轉的刻度標簽。

所以基本上在這里,您擁有在單個命令中擁有漂亮日期軸所需的所有設置。

一個很好的例子可以在 matplotlib 頁面上找到。

另一種對每個刻度標簽應用horizontalalignmentrotation方法是在要更改的刻度標簽上執行for循環:

import numpy as np
import matplotlib.pyplot as plt
import datetime as dt

now = dt.datetime.now()
hours = [now + dt.timedelta(minutes=x) for x in range(0,24*60,10)]
days = [now + dt.timedelta(days=x) for x in np.arange(0,30,1/4.)]
hours_value = np.random.random(len(hours))
days_value = np.random.random(len(days))

fig, axs = plt.subplots(2)
fig.subplots_adjust(hspace=0.75)
axs[0].plot(hours,hours_value)
axs[1].plot(days,days_value)

for label in axs[0].get_xmajorticklabels() + axs[1].get_xmajorticklabels():
    label.set_rotation(30)
    label.set_horizontalalignment("right")

在此處輸入圖片說明

如果您想控制主要和次要刻度的位置,這里是一個示例:

import numpy as np
import matplotlib.pyplot as plt
import datetime as dt

fig, axs = plt.subplots(2)
fig.subplots_adjust(hspace=0.75)
now = dt.datetime.now()
hours = [now + dt.timedelta(minutes=x) for x in range(0,24*60,10)]
days = [now + dt.timedelta(days=x) for x in np.arange(0,30,1/4.)]

axs[0].plot(hours,np.random.random(len(hours)))
x_major_lct = mpl.dates.AutoDateLocator(minticks=2,maxticks=10, interval_multiples=True)
x_minor_lct = matplotlib.dates.HourLocator(byhour = range(0,25,1))
x_fmt = matplotlib.dates.AutoDateFormatter(x_major_lct)
axs[0].xaxis.set_major_locator(x_major_lct)
axs[0].xaxis.set_minor_locator(x_minor_lct)
axs[0].xaxis.set_major_formatter(x_fmt)
axs[0].set_xlabel("minor ticks set to every hour, major ticks start with 00:00")

axs[1].plot(days,np.random.random(len(days)))
x_major_lct = mpl.dates.AutoDateLocator(minticks=2,maxticks=10, interval_multiples=True)
x_minor_lct = matplotlib.dates.DayLocator(bymonthday = range(0,32,1))
x_fmt = matplotlib.dates.AutoDateFormatter(x_major_lct)
axs[1].xaxis.set_major_locator(x_major_lct)
axs[1].xaxis.set_minor_locator(x_minor_lct)
axs[1].xaxis.set_major_formatter(x_fmt)
axs[1].set_xlabel("minor ticks set to every day, major ticks show first day of month")
for label in axs[0].get_xmajorticklabels() + axs[1].get_xmajorticklabels():
    label.set_rotation(30)
    label.set_horizontalalignment("right")

在此處輸入圖片說明

只需使用

ax.set_xticklabels(label_list, rotation=45)

我顯然遲到了,但有一個官方示例使用

plt.setp(ax.get_xticklabels(), rotation=45, ha="right", rotation_mode="anchor")

旋轉標簽,同時保持它們與刻度正確對齊,這既干凈又容易。

參考: https : //matplotlib.org/stable/gallery/images_contours_and_fields/image_annotated_heatmap.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM