Matplotlib是數據可視化中使用的各類繪圖庫中應用較為廣泛的一個,近期使用時遇到大批量數據需要自定義坐標軸標記的需求,搗鼓了很久才搞明白,特此記錄
如何自定義坐標
創建對象、設置畫布后,繪制圖形前,使用 Matplotlib.pyplot.xtick(ticks=mytick, labels=my_label)設置
import Matplotlib.pyplot as plt
x = list(range(1100))
y = [1] * 1100
plt.subplots(figsize=(18,6))
plt.xlabel('time') # 設置x坐標軸的名稱
my_label = ['I am No.3','I am No.4','I am No.999'] # 自定義坐標軸值
plt.grid(b=True) # 開啟網格線
plt.xticks(ticks=[3,14,999],labels=my_label,
rotation=60, ha='right') # 自定義x軸內容
plt.ylabel('whatever') # 設置y坐標軸的名稱
plt.plot(x, y) # 畫圖
上述內容中,plt.xticks(ticks=[3,14,999],labels=my_label,)的ticks與labels長度可以不同,但是不同會導致顯示出的標簽數目不合預期,使用時需要注意。另外,ticks=與labels=可以省略,但省略時順序不能顛倒,即必須先寫坐標顯示位置,再寫坐標內容。
plt.xticks(rotation=60, ha='right')中的rotation提供坐標標簽旋轉,旋轉中心是標簽的中心,所以旋轉后可能出現看起來和坐標點對不齊的情況,這時候就需要使用ha參數選擇標簽的{'left','center','right'}邊緣與坐標點對齊。
上述代碼的運行效果如圖所示:

間隔放置坐標軸標簽的方法
正因此處的xticks()可以幫助我們選擇放置坐標軸的位置,我們可以巧妙的利用它完成間隔設置標簽的需求,只需:
import Matplotlib.pyplot as plt
x = list(range(1100))
y = [1] * 1100
plt.subplots(figsize=(18,6))
plt.xlabel('time') # 設置x坐標軸的名稱
my_tick = list(range(1100)) # 可以用list(range(len(my_label))) 替代
my_label = time_label[:1100] # 有1100個時間字符串的list
plt.grid(b=True)
plt.xticks(my_tick[::100],my_label[::100]
,rotation=60, ha='right') # 利用切片來完成需求
plt.ylabel('whatever')
plt.plot(x, y)
上述代碼的運行效果如圖所示:

如果不加切片,顯示效果將是災難

網上的另一種方法
還有一種網上常見的方法使用matplotlib.pyplot.gca().xaxis.set_major_locator()來調整坐標間隔,但是這種方法調整的是坐標軸上打點的間隔,並不能做到省略某些坐標點。在本文使用的時間字符串time_labellist這種上千坐標標簽的情況下,用此方法只會導致前半部分標簽被分散打在全長度的坐標軸上,請看代碼與截圖:
N = 4
tsm4 = TimeSeriesKMeans(n_clusters=N, max_iter=10).fit(two_week_nor)
time_label = two_week.time.to_list()
for clus in range(N):
plt.subplots(figsize=(18,6))
plt.xlabel('time')
plt.xticks(range(len(time_label)),time_label, rotation=-60, ha='left')
plt.gca().xaxis.set_major_locator(ticker.MultipleLocator(128))
x = two_week_nor[np.where(tsm4.labels_ == clus)].T
for item in x:
plt.plot(item, alpha = 0.6)

可以看到坐標軸只顯示了前半部分的連續坐標,並沒有做到真正的間隔顯示。
