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

问题:更改matplotlib中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的间隔?

I am trying to fix how python plots my data.

Say

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

and

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

Then I would do:

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

and the x axis’ ticks are plotted in intervals of 5. Is there a way to make it show intervals of 1?


回答 0

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

You could explicitly set where you want to tick marks with plt.xticks:

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

For example,

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 was used rather than Python’s range function just in case min(x) and max(x) are floats instead of ints.)


The plt.plot (or ax.plot) function will automatically set default x and y limits. If you wish to keep those limits, and just change the stepsize of the tick marks, then you could use ax.get_xlim() to discover what limits Matplotlib has already set.

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

The default tick formatter should do a decent job rounding the tick values to a sensible number of significant digits. However, if you wish to have more control over the format, you can define your own formatter. For example,

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

Here’s a runnable example:

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

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

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

Another approach is to set the axis locator:

import matplotlib.ticker as plticker

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

There are several different types of locator depending upon your needs.

Here is a full example:

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

回答 2

我喜欢这个解决方案(来自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(),允许自动确定极限,并且以后易于阅读。

I like this solution (from the 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()

This solution give you explicit control of the tick spacing via the number given to ticker.MultipleLocater(), allows automatic limit determination, and is easy to read later.


回答 3

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

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

In case anyone is interested in a general one-liner, simply get the current ticks and use it to set the new ticks by sampling every other tick.

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

回答 4

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

This is a bit hacky, but by far the cleanest/easiest to understand example that I’ve found to do this. It’s from an answer on SO here:

Cleanest way to hide every nth tick label in matplotlib colorbar?

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

Then you can loop over the labels setting them to visible or not depending on the density you want.

edit: note that sometimes matplotlib sets labels == '', so it might look like a label is not present, when in fact it is and just isn’t displaying anything. To make sure you’re looping through actual visible labels, you could try:

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)

回答 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函数。

This is an old topic, but I stumble over this every now and then and made this function. It’s very convenient:

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)

One caveat of controlling the ticks like this is that one does no longer enjoy the interactive automagic updating of max scale after an added line. Then do

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

and run the resadjust function again.


回答 6

我开发了一个优雅的解决方案。考虑我们有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()

I developed an inelegant solution. Consider that we have the X axis and also a list of labels for each point in X.

Example:
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']
Let’s say that I want to show ticks labels only for ‘feb’ and ‘jun’
xlabelsnew = []
for i in xlabels:
    if i not in ['feb','jun']:
        i = ' '
        xlabelsnew.append(i)
    else:
        xlabelsnew.append(i)
Good, now we have a fake list of labels. First, we plotted the original version.
plt.plot(x,y)
plt.xticks(range(0,len(x)),xlabels,rotation=45)
plt.show()
Now, the modified version.
plt.plot(x,y)
plt.xticks(range(0,len(x)),xlabelsnew,rotation=45)
plt.show()

回答 7

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

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

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

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

有点满口,但是很紧凑

if you just want to set the spacing a simple one liner with minimal boilerplate:

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

also works easily for minor ticks:

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

a bit of a mouthfull, but pretty compact


回答 8

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

plt.xticks(xmarks)

这对我有用

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

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

plt.xticks(xmarks)

This worked for me

if you want ticks between [1,5] (1 and 5 inclusive) then replace

length = 5

回答 9

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

Pure Python Implementation

Below’s a pure python implementation of the desired functionality that handles any numeric series (int or float) with positive, negative, or mixed values and allows for the user to specify the desired step size:

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)

Sample Output

# 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]

Sample Usage

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

Notice the x-axis has integer values all evenly spaced by 5, whereas the y-axis has a different interval (the matplotlib default behavior, because the ticks weren’t specified).