更改matplotlib中x或y轴上的"滴答频率"?

Dax*_*liz 419 python matplotlib

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

x = [0,5,9,10,15]
Run Code Online (Sandbox Code Playgroud)

y = [0,1,2,3,4]
Run Code Online (Sandbox Code Playgroud)

然后我会这样做:

matplotlib.pyplot.plot(x,y)
matplotlib.pyplot.show()
Run Code Online (Sandbox Code Playgroud)

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

unu*_*tbu 503

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

plt.xticks(np.arange(min(x), max(x)+1, 1.0))
Run Code Online (Sandbox Code Playgroud)

例如,

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()
Run Code Online (Sandbox Code Playgroud)

(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))
Run Code Online (Sandbox Code Playgroud)

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

ax.xaxis.set_major_formatter(ticker.FormatStrFormatter('%0.1f'))
Run Code Online (Sandbox Code Playgroud)

这是一个可运行的例子:

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()
Run Code Online (Sandbox Code Playgroud)

  • 有没有办法让它仍然决定它自己的限制,但只是改变步长?如果min类似于3523.232512,这个方法不是很好! (65认同)
  • 请注意,`plt.xticks(np.arange(min(x),max(x)+ 1,1.0))`中的`+ 1`是显示最后刻度线所必需的. (3认同)
  • @Corone,自从你提问以来已经有一段时间了,但我在下面发布了一个答案,允许在仍然使用自动边界确定的同时轻松控制步长. (2认同)
  • 有没有相应的日期时间,例如```plt.xticks(np.arange(min(日期),max(日期)+0.1,0.1)```它似乎只绘制年份 (2认同)

rob*_*hat 181

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

import matplotlib.ticker as plticker

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

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

  • 使用日期时,应使用matplotlib.dates模块中的方法.例如`matplotlib.dates.AutoDateLocator()` (29认同)
  • 这不能按预期工作.具体来说,使用日期时,它不会使用适当的日期. (6认同)
  • 它按预期的方式为我工作,有日期.这种解决方案比公认的解决方案容易得多. (3认同)
  • `base=1.0` 实际上是什么意思/做什么? (2认同)
  • base=1.0 表示每个整数都有一个定位器。文档说 MultipleLocator“在视图间隔内的基数的每个整数倍上设置一个刻度”。因此,如果基数 = 2,那么偶数将会打勾,我认为您可以将基数设置为 2.5。 (2认同)

jth*_*mas 107

我喜欢这个解决方案(来自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()
Run Code Online (Sandbox Code Playgroud)

此解决方案可让您通过给定的数字明确控制刻度线间距ticker.MultipleLocater(),允许自动限制确定,并且以后易于阅读.

  • 接得好.当我发布答案时,我没有认出它们.不过,我认为这个演示文稿更容易​​理解. (6认同)
  • 这与[this](/sf/answers/1398109541/)相同。两年后再添加一个相同的答案是没有意义的。 (4认同)
  • 一种方法,无需明确计算滴答! (3认同)
  • 本答案中的书籍参考也提供了更多信息的有用来源。 (2认同)
  • 为了便于将来参考,无需使用相同的解决方案编写新答案,只需编辑另一个答案以使其更加清晰即可。我也发现你的更清楚。 (2认同)

glo*_*pes 79

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

ax.set_xticks(ax.get_xticks()[::2])
Run Code Online (Sandbox Code Playgroud)

  • 它只能减少棍棒的数量,而在问题中(以及我的目标是如何找到它的)是增加它。 (5认同)
  • 这是针对不同刻度类型(str,float,datetime)的唯一可概括的答案 (2认同)
  • 删除非整数的刻度:`ax.set_xticks([如果刻度%1 == 0,则勾选ax.get_xticks()中的刻度)。 (2认同)
  • 我认为这是最好的答案。大多数其他答案都过于复杂且难以应用/概括。谢谢你! (2认同)

cho*_*raf 29

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

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

for label in ax.get_xticklabels()[::2]:
    label.set_visible(False)
Run Code Online (Sandbox Code Playgroud)

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

编辑:请注意,有时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)
Run Code Online (Sandbox Code Playgroud)

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

小智 20

如果您只想将间距设置为一个带有最少样板的简单衬里:

plt.gca().xaxis.set_major_locator(plt.MultipleLocator(1))
Run Code Online (Sandbox Code Playgroud)

对于小蜱虫也很容易:

plt.gca().xaxis.set_minor_locator(plt.MultipleLocator(1))
Run Code Online (Sandbox Code Playgroud)

有点满嘴,但很紧凑


Tom*_*mpa 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)
Run Code Online (Sandbox Code Playgroud)

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

gca().set_ylim(top=new_top) # for example
Run Code Online (Sandbox Code Playgroud)

并再次运行resadjust函数.


Den*_*hos 10

我开发了一个不优雅的解决方案.考虑我们有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']
Run Code Online (Sandbox Code Playgroud) 假设我只想为'feb'和'jun'显示刻度标签
xlabelsnew = []
for i in xlabels:
    if i not in ['feb','jun']:
        i = ' '
        xlabelsnew.append(i)
    else:
        xlabelsnew.append(i)
Run Code Online (Sandbox Code Playgroud) 好的,现在我们有一个假的标签清单.首先,我们绘制了原始版本.
plt.plot(x,y)
plt.xticks(range(0,len(x)),xlabels,rotation=45)
plt.show()
Run Code Online (Sandbox Code Playgroud) 现在,修改后的版本.
plt.plot(x,y)
plt.xticks(range(0,len(x)),xlabelsnew,rotation=45)
plt.show()
Run Code Online (Sandbox Code Playgroud)


Joh*_*y V 9

可通用的一个衬垫,仅导入 Numpy:

ax.set_xticks(np.arange(min(x),max(x),1))
Run Code Online (Sandbox Code Playgroud)

在问题的上下文中设置:

import numpy as np
import matplotlib.pyplot as plt 
fig, ax = plt.subplots()
x = [0,5,9,10,15]
y = [0,1,2,3,4]
ax.plot(x,y)
ax.set_xticks(np.arange(min(x),max(x),1))
plt.show()
Run Code Online (Sandbox Code Playgroud)

怎么运行的:

  1. fig, ax = plt.subplots()给出包含轴的 ax 对象.
  2. np.arange(min(x),max(x),1)给出一个从 x 的最小值到 x 的最大值的区间 1 的数组. 这就是我们想要的新 x 刻度。
  3. ax.set_xticks()更改 ax 对象上的刻度。


小智 6

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

plt.xticks(xmarks)
Run Code Online (Sandbox Code Playgroud)

这对我有用

如果您想要 [1,5](包括 1 和 5)之间的刻度,则替换

length = 5
Run Code Online (Sandbox Code Playgroud)

  • 仅供参考,您可以简单地编写“xmarks = range(1, length+1, 1)”。很确定列表理解是多余的。 (3认同)

kma*_*o23 6

由于上述解决方案都不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()
Run Code Online (Sandbox Code Playgroud)

现在,我们使用新图清理混乱,该图仅将 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()
Run Code Online (Sandbox Code Playgroud)

根据用例,只需更改show_every并使用上述代码来对 X 轴或 Y 轴或两个轴的刻度值进行采样即可调整上述代码。

如果这种基于步长的解决方案不适合,那么如果需要的话,还可以以不规则的间隔填充sparse_xticks或 的值。sparse_yticks


Gre*_*ick 5

纯 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)
Run Code Online (Sandbox Code Playgroud)

样本输出

# 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]
Run Code Online (Sandbox Code Playgroud)

示例用法

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()
Run Code Online (Sandbox Code Playgroud)

样本使用图

请注意,x 轴的整数值均以 5 为单位均匀间隔,而 y 轴具有不同的间隔(matplotlib默认行为,因为未指定刻度)。