簡體   English   中英

更改 x 或 y 軸上的刻度頻率

[英]Changing the tick frequency on the x or y axis

我正在嘗試修復 python 如何繪制我的數據。 說:

x = [0, 5, 9, 10, 15]
y = [0, 1, 2, 3, 4]

matplotlib.pyplot.plot(x, y)
matplotlib.pyplot.show()

x 軸的刻度以 5 為間隔繪制。有沒有辦法讓它顯示 1 的間隔?

您可以使用plt.xticks明確設置要標記的plt.xticks

plt.xticks(np.arange(min(x), max(x)+1, 1.0))

例如,

import numpy as np
import matplotlib.pyplot as plt

x = [0,5,9,10,15]
y = [0,1,2,3,4]
plt.plot(x,y)
plt.xticks(np.arange(min(x), max(x)+1, 1.0))
plt.show()

(使用np.arange而不是 Python 的range函數,以防min(x)max(x)是浮點數而不是整數。)


plt.plot (或ax.plot )函數將自動設置默認的xy限制。 如果您希望保留這些限制,而只是更改刻度線的步長,那么您可以使用ax.get_xlim()來發現 Matplotlib 已經設置的限制。

start, end = ax.get_xlim()
ax.xaxis.set_ticks(np.arange(start, end, stepsize))

默認的刻度格式器應該能很好地將刻度值四舍五入到合理的有效數字位數。 但是,如果您希望對格式有更多的控制,您可以定義自己的格式化程序。 例如,

ax.xaxis.set_major_formatter(ticker.FormatStrFormatter('%0.1f'))

這是一個可運行的示例:

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

x = [0,5,9,10,15]
y = [0,1,2,3,4]
fig, ax = plt.subplots()
ax.plot(x,y)
start, end = ax.get_xlim()
ax.xaxis.set_ticks(np.arange(start, end, 0.712123))
ax.xaxis.set_major_formatter(ticker.FormatStrFormatter('%0.1f'))
plt.show()

另一種方法是設置軸定位器:

import matplotlib.ticker as plticker

loc = plticker.MultipleLocator(base=1.0) # this locator puts ticks at regular intervals
ax.xaxis.set_major_locator(loc)

根據您的需要,有幾種不同類型的定位器。

這是一個完整的例子:

import matplotlib.pyplot as plt
import matplotlib.ticker as plticker

x = [0,5,9,10,15]
y = [0,1,2,3,4]
fig, ax = plt.subplots()
ax.plot(x,y)
loc = plticker.MultipleLocator(base=1.0) # this locator puts ticks at regular intervals
ax.xaxis.set_major_locator(loc)
plt.show()

我喜歡這個解決方案(來自Matplotlib Plotting Cookbook ):

import matplotlib.pyplot as plt
import matplotlib.ticker as ticker

x = [0,5,9,10,15]
y = [0,1,2,3,4]

tick_spacing = 1

fig, ax = plt.subplots(1,1)
ax.plot(x,y)
ax.xaxis.set_major_locator(ticker.MultipleLocator(tick_spacing))
plt.show()

該解決方案通過給ticker.MultipleLocater()的數字顯式控制刻度間距,允許自動確定限制,並且以后易於閱讀。

如果有人對一般的單行感興趣,只需獲取當前的刻度並使用它通過每隔一個刻度采樣來設置新的刻度。

ax.set_xticks(ax.get_xticks()[::2])

這有點 hacky,但迄今為止我發現這樣做的最干凈/最容易理解的示例。 它來自此處的 SO 答案:

在 matplotlib 顏色欄中隱藏每個第 n 個刻度標簽的最干凈方法?

for label in ax.get_xticklabels()[::2]:
    label.set_visible(False)

然后你可以循環標簽,根據你想要的密度將它們設置為可見或不可見。

編輯:請注意,有時 matplotlib 會設置標簽 == '' ,因此看起來標簽可能不存在,而實際上標簽存在並且不顯示任何內容。 為確保您循環瀏覽實際可見的標簽,您可以嘗試:

visible_labels = [lab for lab in ax.get_xticklabels() if lab.get_visible() is True and lab.get_text() != '']
plt.setp(visible_labels[::2], visible=False)

如果您只想將間距設置為一個帶有最少樣板的簡單襯里:

plt.gca().xaxis.set_major_locator(plt.MultipleLocator(1))

對於小蜱蟲也很容易:

plt.gca().xaxis.set_minor_locator(plt.MultipleLocator(1))

有點滿嘴,但很緊湊

這是一個古老的話題,但我時不時地偶然發現並制作了這個功能。 非常方便:

import matplotlib.pyplot as pp
import numpy as np

def resadjust(ax, xres=None, yres=None):
    """
    Send in an axis and I fix the resolution as desired.
    """

    if xres:
        start, stop = ax.get_xlim()
        ticks = np.arange(start, stop + xres, xres)
        ax.set_xticks(ticks)
    if yres:
        start, stop = ax.get_ylim()
        ticks = np.arange(start, stop + yres, yres)
        ax.set_yticks(ticks)

像這樣控制刻度的一個警告是,在添加一行之后,人們不再享受最大比例的交互式自動更新。 然后做

gca().set_ylim(top=new_top) # for example

並再次運行重新調整功能。

我開發了一個不雅的解決方案。 考慮我們有 X 軸以及 X 中每個點的標簽列表。

例子:
plt.plot(x,y)
plt.xticks(range(0,len(x)),xlabels,rotation=45)
plt.show()
假設我只想顯示“feb”和“jun”的刻度標簽
xlabelsnew = [] for i in xlabels: if i not in ['feb','jun']: i = ' ' xlabelsnew.append(i) else: xlabelsnew.append(i)
很好,現在我們有一個假的標簽列表。 首先,我們繪制了原始版本。
 plt.plot(x,y) plt.xticks(range(0,len(x)),xlabels,rotation=45) plt.show()
現在,修改后的版本。
 plt.plot(x,y) plt.xticks(range(0,len(x)),xlabelsnew,rotation=45) plt.show()

純 Python 實現

下面是所需功能的純 python 實現,它處理任何具有正值、負值或混合值的數字系列(整數或浮點數),並允許用戶指定所需的步長:

import math

def computeTicks (x, step = 5):
    """
    Computes domain with given step encompassing series x
    @ params
    x    - Required - A list-like object of integers or floats
    step - Optional - Tick frequency
    """
    xMax, xMin = math.ceil(max(x)), math.floor(min(x))
    dMax, dMin = xMax + abs((xMax % step) - step) + (step if (xMax % step != 0) else 0), xMin - abs((xMin % step))
    return range(dMin, dMax, step)

樣本輸出

# Negative to Positive
series = [-2, 18, 24, 29, 43]
print(list(computeTicks(series)))

[-5, 0, 5, 10, 15, 20, 25, 30, 35, 40, 45]

# Negative to 0
series = [-30, -14, -10, -9, -3, 0]
print(list(computeTicks(series)))

[-30, -25, -20, -15, -10, -5, 0]

# 0 to Positive
series = [19, 23, 24, 27]
print(list(computeTicks(series)))

[15, 20, 25, 30]

# Floats
series = [1.8, 12.0, 21.2]
print(list(computeTicks(series)))

[0, 5, 10, 15, 20, 25]

# Step – 100
series = [118.3, 293.2, 768.1]
print(list(computeTicks(series, step = 100)))

[100, 200, 300, 400, 500, 600, 700, 800]

示例用法

import matplotlib.pyplot as plt

x = [0,5,9,10,15]
y = [0,1,2,3,4]
plt.plot(x,y)
plt.xticks(computeTicks(x))
plt.show()

樣本使用圖

請注意,x 軸的整數值均以 5 為單位均勻間隔,而 y 軸的間隔不同( matplotlib默認行為,因為未指定刻度)。

xmarks=[i for i in range(1,length+1,1)]

plt.xticks(xmarks)

這對我有用

如果你想在 [1,5] (包括 1 和 5)之間打勾,然后替換

length = 5

由於上述解決方案都不適用於我的用例,因此我在這里提供了一個使用None (雙關語!)的解決方案,它可以適用於各種場景。

這是一段示例代碼,它在XY軸上產生雜亂的刻度。

# Note the super cluttered ticks on both X and Y axis.

# inputs
x = np.arange(1, 101)
y = x * np.log(x) 

fig = plt.figure()     # create figure
ax = fig.add_subplot(111)
ax.plot(x, y)
ax.set_xticks(x)        # set xtick values
ax.set_yticks(y)        # set ytick values

plt.show()

現在,我們用一個新圖來清理混亂,該圖僅顯示 x 和 y 軸上的一組稀疏值作為刻度。

# inputs
x = np.arange(1, 101)
y = x * np.log(x)

fig = plt.figure()       # create figure
ax = fig.add_subplot(111)
ax.plot(x, y)

ax.set_xticks(x)
ax.set_yticks(y)

# which values need to be shown?
# here, we show every third value from `x` and `y`
show_every = 3

sparse_xticks = [None] * x.shape[0]
sparse_xticks[::show_every] = x[::show_every]

sparse_yticks = [None] * y.shape[0]
sparse_yticks[::show_every] = y[::show_every]

ax.set_xticklabels(sparse_xticks, fontsize=6)   # set sparse xtick values
ax.set_yticklabels(sparse_yticks, fontsize=6)   # set sparse ytick values

plt.show()

根據用例,可以簡單地通過更改show_every並使用它來對 X 或 Y 或兩個軸的刻度值進行采樣來調整上述代碼。

如果這種基於步長的解決方案不適合,那么如果需要的話,還可以以不規則的間隔填充sparse_xtickssparse_yticks的值。

您可以遍歷標簽並顯示或隱藏您想要的標簽:

   for i, label in enumerate(ax.get_xticklabels()):
        if i % interval != 0:
            label.set_visible(False)

如果您需要使用舊的刻度標簽更改刻度標簽頻率以及刻度頻率,則依次使用set_xticksset_xticklabels會拋出如下所示的 ValueError:

ValueError: The number of FixedLocator locations (5), usually from 
a call to set_ticks, does not match the number of labels (3).

解決此問題的一種方法是使用set()方法同時設置兩者。 一個例子可能會更好地說明這一點。

import pandas as pd
ax = pd.Series(range(20), index=pd.date_range('2020', '2024', 20).date).plot()
ax.set_xticks(ax.get_xticks()[::2])             # <---- error   
ax.set_xticklabels(ax.get_xticklabels()[::2]);  # <---- error


ax = pd.Series(range(20), index=pd.date_range('2020', '2024', 20).date).plot()
ax.set(xticks=ax.get_xticks()[::2], 
       xticklabels=ax.get_xticklabels()[::2]);  # <---- OK

結果


對於這種特定情況, matplotlib.dates.YearLocatormatplotlib.dates.DateFormatter更靈活(例如ax.xaxis.set_major_locator(matplotlib.dates.YearLocator()) )並且可能是設置刻度標簽的首選方式,但上面的帖子提供了快速修復常見錯誤。

可推廣的一個班輪,僅導入 Numpy:

import numpy as np
ax.set_xticks(np.arange(min(ax.get_xticks()),max(ax.get_xticks()),1));

暫無
暫無

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

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