关于python:更改matplotlib中x或y轴上的“tick frequency”?

Changing the “tick frequency” on x or y axis in matplotlib?

我试图修复python如何绘制我的数据。

1
x = [0,5,9,10,15]

1
y = [0,1,2,3,4]

然后我会这样做:

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

并且x轴'刻度以5为间隔绘制。有没有办法让它显示间隔为1?


您可以使用plt.xticks明确设置要勾选标记的位置:

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

例如,

1
2
3
4
5
6
7
8
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已设置的限制。

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

默认的刻度格式化程序应该做一个不错的工作,将刻度值四舍五入到有效数字的有效位数。但是,如果您希望对格式有更多控制权,可以定义自己的格式化程序。例如,

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

这是一个可运行的例子:

1
2
3
4
5
6
7
8
9
10
11
12
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()


另一种方法是设置轴定位器:

1
2
3
4
import matplotlib.ticker as plticker

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

根据您的需要,有几种不同类型的定位器。

这是一个完整的例子:

1
2
3
4
5
6
7
8
9
10
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):

1
2
3
4
5
6
7
8
9
10
11
12
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()的数字,您可以明确控制节拍间距,允许自动限制确定,并且以后易于阅读。


如果有人对一般的单行程感兴趣,只需获取当前的刻度并使用它通过每隔一个刻度采样来设置新的刻度。

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


这有点hacky,但到目前为止,我发现这是最干净/最容易理解的例子。这是来自SO的回答:

在matplotlib colorbar中隐藏每个第n个刻度标签最干净的方法?

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

然后,您可以循环标签,将它们设置为可见或不可见,具体取决于您想要的密度。

编辑:请注意,有时matplotlib设置标签== '',因此它可能看起来像标签不存在,实际上它只是没有显示任何东西。要确保循环显示实际的可见标签,您可以尝试:

1
2
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)


这是一个古老的话题,但我时不时地偶然发现这个并发挥了这个功能。这很方便:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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)

控制这样的刻度的一个警告是,在添加的线之后,人们不再享受最大规模的交互式自动更新。然后做

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

并再次运行resadjust函数。


我开发了一个不优雅的解决方案。考虑我们有X轴以及X中每个点的标签列表。

例:

1
2
3
4
5
import matplotlib.pyplot as plt

x = [0,1,2,3,4,5]
y = [10,20,15,18,7,19]
xlabels = ['jan','feb','mar','apr','may','jun']

假设我只想为'feb'和'jun'显示刻度标签

1
2
3
4
5
6
7
xlabelsnew = []
for i in xlabels:
    if i not in ['feb','jun']:
        i = ' '
        xlabelsnew.append(i)
    else:
        xlabelsnew.append(i)

好的,现在我们有一个假的标签清单。首先,我们绘制了原始版本。

1
2
3
plt.plot(x,y)
plt.xticks(range(0,len(x)),xlabels,rotation=45)
plt.show()

现在,修改后的版本。

1
2
3
plt.plot(x,y)
plt.xticks(range(0,len(x)),xlabelsnew,rotation=45)
plt.show()

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

plt.xticks(xmarks)

这对我有用

如果你想要[1,5](1和5之间)之间的刻度,那么替换

1
length = 5


这是一个所需功能的纯python实现,它处理具有正值,负值或混合值的任何数字系列(int或float):

1
2
3
4
5
6
7
8
9
10
11
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
   """

    import math as Math
    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)

样本输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 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]

和样品用法:

1
2
3
4
5
6
7
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()