簡體   English   中英

如何更改pyplot中Y軸上標簽之間的距離?

[英]How to change distances between labels on Y axis in pyplot?

我正在繪制 x 軸上的時間和 y 軸上的檢查點的“旅行時間”圖(檢查點只是名稱,一個檢查點對應一個時間戳)。 繪圖本身的代碼是:

if checkpoints:
  plt.plot_date(timestamps,checkpoints,color = "b",linestyle='solid')
else:
  plt.plot_date(timestamps,distances,color = "b",linestyle='solid')

時間戳:小時列表:分鍾,檢查點:字符串列表,距離:整數列表

由於檢查點之間的距離不同,我需要在 y 軸上以不同的間距重新繪制繪圖。 我想,這可以通過使用距離數組作為第二個參數來實現,但我不知道應該如何重命名距離標簽,以便它們與檢查點相對應。

編輯:

使用的數據:

時間戳:它們由命令datetime.strptime(timestamp, "%H:%M")並收集在一個數組中。 輸入數據如下:

4:45 4:48 4:51 4:52 4:53 4:54 4:55 4:56 5:15 5:19 5:24 5:25 5:26 5:28 5:29 5:30 5:33 5:35 5:39 5:40 5:42 5:43 5:44 5:45 5:39 5:40 5:46 5:47 5:48 5:50 5:51 5:52

檢查點:字符串數組,長度與時間戳相同。 它們會定期重復以匹配時間戳:

[ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H','A', 'B', 'C', 'D', 'E', 'F', 'G', 'H','A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' ]

距離:類似於檢查點,但它們是整數,而不是字符串。

[ 0, 9, 12, 16, 18, 21, 23, 24, 0, 9, 12, 16, 18, 21, 23, 24, 0, 9, 12, 16, 18, 21, 23, 24, 0, 9, 12, 16, 18, 21, 23, 24 ]

生成帶有檢查點和時間戳的輸出:

示例 1

我不喜歡檢查點之間的均勻距離。

我想實現這一點 - 帶有距離和時間戳的輸出(Y 軸上的數字是與檢查點 A 的距離),但帶有來自第一個示例的標簽:

示例 2

成功的關鍵是使用檢查點的y距離,而不是它們的文本標簽。

您在這里需要的數據是:

ts = [
    '4:45', '4:48', '4:51', '4:52', '4:53', '4:54', '4:55', '4:56',
    '5:15', '5:19', '5:24', '5:25', '5:26', '5:28', '5:29', '5:30',
    '5:33', '5:35', '5:39', '5:40', '5:42', '5:43', '5:44', '5:45',
    '5:39', '5:40', '5:46', '5:47', '5:48', '5:50', '5:51', '5:52']
chkDist = [0, 9, 12, 16, 18, 21, 23, 24]
chkLbl  = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']

檢查點距離和標簽沒有重復。

讓我們從數據轉換開始。 使用以下命令生成數據幀:

  • 每行 4 列(將ts切成行然后轉換),
  • 索引為dist
  • 並將字符串轉換為datetime

執行此操作的代碼是:

timestamps = pd.DataFrame(np.array(ts).reshape((4, -1)).T,
    index=chkDist).apply(pd.to_datetime)

日期部分取自當天,但實際上無關緊要。

還將檢查點距離和標簽轉換為Series

chkLabels = pd.Series(chkLbl, index=chkDist)

然后生成你的圖片如下:

import matplotlib.pyplot as plt
import matplotlib.dates as mdates

fig, ax = plt.subplots(figsize=(6, 4), constrained_layout=True)
plt.plot_date(timestamps, timestamps.index, color='b', linestyle='solid')
ax.xaxis.set_major_locator(mdates.MinuteLocator(byminute=range(0,60,15)))
ax.xaxis.set_major_formatter(mdates.DateFormatter(fmt='%H:%M'))
plt.xticks(rotation=30)
for dist, lbl in chkLabels.iteritems():
    plt.text(xLbl, dist, lbl, ha='center', va='center')
ax.set_yticks(chkDist, minor=True)
plt.grid(which='minor', linestyle='--')
plt.grid(which='major')
plt.show()

請注意,時間戳是一個DataFrame ,因此從它的每一列生成單獨的行。 我使用MinuteLocator每 15 分鍾有x 個標簽,並使用DateFormatter來格式化它們。

為了打印檢查點標簽,我使用了額外的循環,遍歷chkLabels並打印每個標簽。

但是請注意, plt.text 的文本坐標以數據坐標表示,因此:

  • y坐標取自chkLabels的索引,
  • x坐標表示為最短時間 - 10 min

最后一步是打印網格。 對於次要線,我使用了set_yticksy取自chkDist 然后我調用plt.grid ,分別為次要線,明確指定線型,​​並為主要線,使用默認屬性。

對於您的數據,我得到以下結果:

在此處輸入圖片說明

請注意,檢查點標簽有時彼此非常接近(在本例中為GH )。 因此,如果它們相互重疊,您應該修改代碼以僅打印選定的標簽,例如通過從chkLabels 中刪除一些元素。

暫無
暫無

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

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