簡體   English   中英

如何在matplotlib中移動刻度標簽?

[英]How to move a tick's label in matplotlib?

我想沿 x 軸水平移動一些刻度的標簽,而不移動相應的刻度。

更具體地說,當使用plt.setp旋轉標簽時,標簽文本的中心與刻度保持對齊。 我想將這些標簽向右移動,以便標簽的近端對齊,而不是如下圖所示。

在此處輸入圖片說明

我知道這篇文章這一個,但答案很有意思組裝機,而不是嚴格的問題的答案。

我的代碼:

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

# my fake data
dates = np.array([datetime.datetime(2000,1,1) + datetime.timedelta(days=i) for i in range(365*5)])
data = np.sin(np.arange(365*5)/365.0*2*np.pi - 0.25*np.pi) + np.random.rand(365*5) /3

# creates fig with 2 subplots
fig = plt.figure(figsize=(10.0, 6.0))
ax = plt.subplot2grid((2,1), (0, 0))
ax2 = plt.subplot2grid((2,1), (1, 0))
## plot dates
ax2.plot_date( dates, data )

# rotates labels 
plt.setp( ax2.xaxis.get_majorticklabels(), rotation=-45 ) 

# try to shift labels to the right
ax2.xaxis.get_majorticklabels()[2].set_y(-.1)
ax2.xaxis.get_majorticklabels()[2].set_x(10**99)

plt.show()

奇怪的是, set_y行為符合預期,但即使我將x設置為 fantasillion,標簽也不會移動一毫。 (使用plot_date可能會引入額外的混亂,但實際上同樣發生在plot 。)

首先,讓我們使用mcve來顯示問題。

import numpy as np
import datetime
import matplotlib.pyplot as plt
plt.rcParams["date.autoformatter.month"] = "%b %Y"

# my fake data
dates = np.array([datetime.datetime(2000,1,1) + datetime.timedelta(days=i) for i in range(365)])
data = np.sin(np.arange(365)/365.0*2*np.pi - 0.25*np.pi) + np.random.rand(365) /3

# creates fig with 2 subplots
fig, ax = plt.subplots(figsize=(6,2))
## plot dates
ax.plot_date( dates, data )

# rotates labels 
plt.setp( ax.xaxis.get_majorticklabels(), rotation=-45 ) 

plt.tight_layout()
plt.show()

在此處輸入圖片說明

現在正如其他答案已經指出的那樣,您可以使用文本的水平對齊方式。

# rotates labels and aligns them horizontally to left 
plt.setp( ax.xaxis.get_majorticklabels(), rotation=-45, ha="left" )

在此處輸入圖片說明

您可以使用rotation_mode參數讓旋轉發生在文本的左上角,在這種情況下會得到更好的結果。

# rotates labels and aligns them horizontally to left 
plt.setp( ax.xaxis.get_majorticklabels(), rotation=-45, ha="left", rotation_mode="anchor") 

在此處輸入圖片說明

如果這些選項不夠細粒度,即您想更准確地定位標簽,例如將其移動到一邊一些點,您可以使用變換。 以下將使用matplotlib.transforms.ScaledTranslation在水平方向上將標簽偏移 5 個點。

import matplotlib.transforms

plt.setp( ax.xaxis.get_majorticklabels(), rotation=-45) 

# Create offset transform by 5 points in x direction
dx = 5/72.; dy = 0/72. 
offset = matplotlib.transforms.ScaledTranslation(dx, dy, fig.dpi_scale_trans)

# apply offset transform to all x ticklabels.
for label in ax.xaxis.get_majorticklabels():
    label.set_transform(label.get_transform() + offset)

在此處輸入圖片說明

與例如@explorerDude 提供的解決方案相比,這樣做的優點是偏移量與圖中的數據無關,因此它通常適用於任何繪圖,並且對於給定的字體大小看起來相同。

代替

ax2.xaxis.get_majorticklabels()[2].set_y(-.1)
ax2.xaxis.get_majorticklabels()[2].set_x(10**99)

set_horizontalalignment()的每個刻度使用set_horizontalalignment()

for tick in ax2.xaxis.get_majorticklabels():
    tick.set_horizontalalignment("left")

導致:

我找到了一種方法,可以任意精確地移動 x 軸的刻度標簽,但這種方法非常接近高聳於瘋狂之海之上的陡峭而滑溜的懸崖。 所以只有非常勇敢或絕望的人才應該繼續閱讀……

話雖如此,問題是在渲染繪圖時設置了標簽的 x 位置(我沒有研究那部分代碼,但這是我的理解)。 所以你用 set_x() 做的一切都會在以后被覆蓋。 但是,有一種方法可以解決這個問題:您可以對某些刻度進行猴子補丁 set_x,這樣標簽就不會繪制在渲染器想要繪制它們的位置:

import types
SHIFT = 10. # Data coordinates
for label in ax2.xaxis.get_majorticklabels():
    label.customShiftValue = SHIFT
    label.set_x = types.MethodType( lambda self, x: matplotlib.text.Text.set_x(self, x-self.customShiftValue ), 
                                    label, matplotlib.text.Text )

您可以僅對要移動的標簽有選擇地執行此操作,當然您也可以為每個標簽使用不同的移動。

如果有人知道如何在較低的瘋狂水平上做到這一點,我會非常感興趣......

另一種進行水平對齊的方法:

plt.xticks(ha='left')

暫無
暫無

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

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