我正在尝试修复 python 如何绘制我的数据。说:
x = [0,5,9,10,15]
y = [0,1,2,3,4]
matplotlib.pyplot.plot(x,y)
matplotlib.pyplot.show()
x 轴的刻度以 5 的间隔绘制。有没有办法让它显示 1 的间隔?
pyplot.locator_params(nbins=4)
您可以使用 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
)函数将自动设置默认的 x
和 y
限制。如果您希望保持这些限制,并且只更改刻度线的步长,那么您可以使用 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.dates.AutoDateLocator()
base=1.0
实际上是什么意思/做什么?
我喜欢这个解决方案(来自 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])
ax.set_xticks([tick for tick in ax.get_xticks() if tick % 1 == 0])
这有点老套,但到目前为止,我发现这样做是最干净/最容易理解的示例。这是来自这里的答案:
Cleanest way to hide every nth tick label in matplotlib colorbar?
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)
ax.get_xticklabels()[1::2]
是要隐藏的标签。
''
,因此当您遍历它们时,您正在制作空的 xticklabels 不可见(这对可视化没有影响,但可能意味着您'不拉正确的标签)。您可以尝试:vis_labels = [label for label in ax.get_xticklabels() if label.get_visible() is True]; plt.setp(vis_labels[::2], visible==False)
如果您只想将间距设置为具有最少样板的简单单行:
plt.gca().xaxis.set_major_locator(plt.MultipleLocator(1))
也适用于小蜱:
plt.gca().xaxis.set_minor_locator(plt.MultipleLocator(1))
有点满口,但非常紧凑
plt.MultipleLocator(arg)
是滴答间隔。因此,如果您希望您的刻度彼此相距 5 个单位,只需使用 plt.MultipleLocator(5)
。否则最喜欢这个解决方案。谢谢!
这是一个古老的话题,但我时不时地偶然发现这个并制作了这个功能。非常方便:
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 功能。
我开发了一个不优雅的解决方案。考虑我们有 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']
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 实现,它处理具有正、负或混合值的任何数字系列(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()
https://i.stack.imgur.com/imxIG.png
请注意,x 轴的整数值均以 5 为间隔均匀分布,而 y 轴的间隔不同(matplotlib
默认行为,因为未指定刻度)。
通用的一个班轮,仅进口 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()
这个怎么运作:
fig, ax = plt.subplots() 给出了包含轴的 ax 对象。 np.arange(min(x),max(x),1) 给出从 x 的最小值到 x 的最大值的区间为 1 的数组。这是我们想要的新的 x 刻度。 ax.set_xticks() 更改 ax 对象上的刻度。
xmarks=[i for i in range(1,length+1,1)]
plt.xticks(xmarks)
这对我有用
如果您想要 [1,5](包括 1 和 5)之间的刻度,则替换
length = 5
xmarks = range(1, length+1, 1)
。很确定列表理解是多余的。
由于上述解决方案没有一个适用于我的用例,因此我在这里提供了一个使用 None
(双关语!)的解决方案,它可以适应各种场景。
这是一段代码示例,它会在 X
和 Y
轴上产生杂乱的刻度。
# 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_xticks
或 sparse_yticks
的值。
您可以遍历标签并显示或隐藏您想要的标签:
for i, label in enumerate(ax.get_xticklabels()):
if i % interval != 0:
label.set_visible(False)
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)
。plt.xticks(np.arange(min(dates), max(dates)+0.1,0.1)
?似乎只绘制年份