更改matplotlib中x或y轴上的“刻度频率”?


477

我正在尝试修复python如何绘制我的数据。

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

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

然后我会做:

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

并且x轴的刻度线以5的间隔绘制。是否有办法使其显示1的间隔?


6
尽管滴答在这里是合适的词,但是将滴答更改为步长肯定会引导更多的新手解决这个问题。
西伯斯赌博

9
密切相关的问题:stackoverflow.com/questions/6682784/…和一个很好的解决方案:pyplot.locator_params(nbins=4)
Jan-Philip Gehrcke博士2014年

不幸的是
nmats

Answers:


583

您可以使用以下命令显式设置要在标记上打勾的位置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()

72
有没有办法让它仍然确定自己的极限,而只是改变步长?如果最小值是3523.232512,则此方法不是很好!
Korone

3
@Corone,自您询问以来已经有一段时间了,但是我在下面发布了一个答案,该答案可以轻松控制步长,同时仍使用自动边界确定。
jthomas

3
请注意,必须输入+1in plt.xticks(np.arange(min(x), max(x)+1, 1.0))才能显示最后一个刻度。
亚历克斯·威利森

1
是的,np.arange(start, stop)半开间隔生成值[start, stop),包括start但不包括stop。所以我曾经max(x)+1确保将max(x)其包括在内。
unutbu

4
日期时间等价 plt.xticks(np.arange(min(dates), max(dates)+0.1,0.1)吗?看来只有一年了
WBM

207

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

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()

7
这不能按预期方式工作。具体来说,在使用日期时,它不会使用适当的日期。
克里斯·冯内斯贝克

35
使用日期时,应使用matplotlib.dates模块中的方法。例如matplotlib.dates.AutoDateLocator()
robochat 2014年

3
它符合我的预期,并带有日期。这种解决方案比公认的解决方案容易得多。
巴勃罗·苏

base=1.0实际上是什么意思?
javadba

base = 1.0表示每个整数都有一个定位符。该文档说,MultipleLocator“在视图间隔内的一个基数的每个整数倍上设置一个刻度”。因此,如果base = 2,那么偶数会出现一个勾号,我认为您可以将base = 2.5放入事件中。
robochat

124

我喜欢这个解决方案(来自Matplotlib绘图食谱):

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(),允许自动确定极限,并且以后易于阅读。


3
一种无需显式计算报价的方法!
Zelphir Kaltstahl,

4
这和这个答案是一样的。两年后再添加一个相同的答案是没有意义的。
ImportanceOfBeingErnest

6
接得好。发布答案时,我没有意识到它们是一样的。不过,我认为此演示文稿更容易​​理解。
jthomas

此答案中的书参考还提供了有用的信息,以获取更多信息。
史蒂文·霍维尔

1
这与三年前出现的robochat的答案相同。
MERose

90

如果有人对通用单线感兴趣,只需获取当前的报价,并通过对其他报价进行采样就可以使用它来设置新的报价。

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

3
这是针对不同刻度类型(str,float,datetime)的唯一可概括性答案
Ryszard Cetnarski 18/09/20

2
删除非整数刻度: ax.set_xticks([tick for tick in ax.get_xticks() if tick % 1 == 0])
user2839288

上面有很多详细的解决方案,但是我同意这是最简洁的。您甚至可以提取ax.get_xticks()的长度,然后通过该长度除以所需的刻度数来设置切片频率。
Iain D

我认为这是最好的答案。大多数其他答案过于复杂,难以应用/概括。谢谢!
Seankala

2
它只能减少摇杆的数量,而问题(以及我的目标是如何找到它)是增加摇杆的数量。
阿列克谢·马蒂安诺夫

36

这有点棘手,但是到目前为止,我发现这样做是最干净/最容易理解的示例。这是从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)

3
这是最简单和通用的解决方案。微小的调整:通常ax.get_xticklabels()[1::2]是要隐藏的标签。
jolvi

这不适用于matplotlib.finance.candlestick2
BCR

@BCR可能是某些xticklabel只是设置为,''以便当您遍历它们时,您正在使xticklabel变为空的不可见(这对可视化效果没有影响,但可能意味着您没有拉动正确的标签)。您可以尝试: vis_labels = [label for label in ax.get_xticklabels() if label.get_visible() is True]; plt.setp(vis_labels[::2], visible==False)
choldgraf '16

15

这是一个古老的话题,但是我时不时地碰到这个问题,并做了这个功能。这很方便:

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

并再次运行resadjust函数。


11

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

例:
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”的刻度标签
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()

6

如果您只想设置间距最小的简单衬板:

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

对于较小的滴答声也很容易工作:

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

有点满口,但是很紧凑


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

plt.xticks(xmarks)

这对我有用

如果您想在[1,5](包括1和5)之间打勾,请替换

length = 5

1
费,你可以简单地写xmarks = range(1, length+1, 1)。可以肯定,列表理解是多余的。
Neal

2

纯Python实现

以下是所需功能的纯python实现,该功能可处理带有正,负或混合值的任何数字系列(int或float),并允许用户指定所需的步长:

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默认行为,因为未指定刻度)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.