改变x或y轴上的滴答频率

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

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


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

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

1505867 次浏览

您可以显式设置要使用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)是浮点数而不是int。)


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

这是一个老话题了,但我偶尔会偶然发现这个,做了这个功能。它非常方便:

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中每个点的标签列表。

示例:
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()

这有点老套,但到目前为止,这是我发现的最干净/最容易理解的例子。它来自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)

我喜欢这个解决方案(来自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()的数字显式控制刻度行间距,允许自动限制确定,并且易于以后阅读。

如果有人对一般的一行代码感兴趣,只需获取当前的报价,并通过每隔一个报价采样来设置新的报价。

ax.set_xticks(ax.get_xticks()[::2])
xmarks=[i for i in range(1,length+1,1)]


plt.xticks(xmarks)

这招对我管用

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

length = 5

纯Python实现

下面是所需功能的纯python实现,它处理具有正、负或混合值的任何数字系列(int或浮点数),并允许用户指定所需的步长:

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

如果你只是想设置行间距一个简单的一行最小样板:

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

也很容易为小滴答:

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

有点多,但很紧凑

由于上述解决方案中的适用于我的用例,因此在这里我提供了一个使用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的值,如果这是需要的。

可泛化的一个班轮,只有Numpy导入:

ax.set_xticks(np.arange(min(x),max(x),1))

在问题的上下文中设置:

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

它是如何工作的:

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

您可以循环浏览标签并显示或隐藏所需的标签:

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