Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何根据序列的实际值设置x记号标签_Python_Matplotlib - Fatal编程技术网

Python 如何根据序列的实际值设置x记号标签

Python 如何根据序列的实际值设置x记号标签,python,matplotlib,Python,Matplotlib,我试图设置x记号标签,但允许matplotlib决定在何处放置记号。不幸的是,当我设置x记号标签时,matplotlib将仅对已显示的记号使用标签字符串 例如: import matplotlib.pyplot as plt fig = plt.figure() ax = fig.add_subplot(111) xs = range(26) ys = range(26) ax.plot(xs, ys) ax.set_xticklabels(list('abcdefghijklmnopqrst

我试图设置x记号标签,但允许matplotlib决定在何处放置记号。不幸的是,当我设置x记号标签时,matplotlib将仅对已显示的记号使用标签字符串

例如:

import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111)
xs = range(26)
ys = range(26)
ax.plot(xs, ys)
ax.set_xticklabels(list('abcdefghijklmnopqrstuvwxyz'))
plt.show()
这使得:

这对我来说很不直观;我希望标签与它们显示的点相对应。(但是,我可以理解,当绘制不使用相同x值的多个系列时,此行为更有用。)

NB:我不希望所有26个字母都是记号。相反,我只想要6(正如matplotlib所建议的),但这6应该适合他们的位置。这样就可以很容易地更改图的大小,而无需手动重新计算新的刻度标签

import matplotlib.pyplot as pl
fig = pl.figure()
ax = fig.add_subplot(111)
xs = range(26)
ys = range(26)
_ = ax.plot(xs, ys)
alph = list('abcdefghijklmnopqrstuvwxyz')
ax.set_xticks(xs)
ax.set_xticklabels(alph)
pl.savefig('ticklabels.png', dpi=300)

如何才能达到预期的结果?

您需要在标签之前指定勾号位置。为您的示例获得所需结果的最简单方法是在设置记号标签之前添加
ax.set_xticks(xs)

import matplotlib.pyplot as pl
fig = pl.figure()
ax = fig.add_subplot(111)
xs = range(26)
ys = range(26)
_ = ax.plot(xs, ys)
alph = list('abcdefghijklmnopqrstuvwxyz')
ax.set_xticks(xs)
ax.set_xticklabels(alph)
pl.savefig('ticklabels.png', dpi=300)

编辑:我建议以下内容来满足您对更通用解决方案的需求:

from matplotlib.ticker import MaxNLocator
import matplotlib.pyplot as pl
import numpy as np

alph = list('abcdefghijklmnopqrstuvwxyz')
nticks = 8

fig, ax = pl.subplots()
xs = np.linspace(-10., 10., 100)
ys = np.polyval([1., 2., 3.], xs)

_ = ax.plot(xs, ys)

ax.xaxis.set_major_locator(MaxNLocator(nticks))
ax.set_xticklabels(alph[::int(len(alph)/nticks)])

pl.savefig('ticklabels.png', dpi=300)
使用指定记号的数量,并通过切片将其映射到字母表

不过,我不确定MaxNLocator返回所需滴答数的可靠性。如注释中所述,您可以简单地使用
len(ax.getxticks())
来获取刻度数


我认为最合适的解决方案是使用
FuncFormatter
,它将允许您查找所需的刻度标签值,并允许matplotlib确定刻度的位置和数量:

import matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter, MaxNLocator
fig = plt.figure()
ax = fig.add_subplot(111)
xs = range(26)
ys = range(26)
labels = list('abcdefghijklmnopqrstuvwxyz')


def format_fn(tick_val, tick_pos):
    if int(tick_val) in xs:
        return labels[int(tick_val)]
    else:
        return ''
ax.xaxis.set_major_formatter(FuncFormatter(format_fn))
ax.xaxis.set_major_locator(MaxNLocator(integer=True))
ax.plot(xs, ys)
plt.show()
这将为您提供:

(感谢Daniel Lenz的指点和其他建议)

NB:


正如tcaswell所提到的,
xaxis.set\u major\u定位器(MaxNLocator(integer=True))
用于确保刻度仅放在整数值上。

谢谢。然而,正如我所提到的,我想保留用于确定应该有多少个刻度以及间距的智能。在这个例子中,我不想要所有26个字母,就像第一张图片中的6个,但它们应该是合适的。你想要一个更一般的解决方案,即将你的x范围映射到字母a-z上,还是你总是有那26个x值?我想要一个更一般的解决方案。x轴上的值和图形的大小将发生变化。您是否可以不使用MaxNLocator而简单地使用
len(ax.get_xticks())
,从而将刻度数保留在matplotlib上,使用
FuncFormatter
和查找x记号标签的函数是否有效?这是
set\u ticklabels
危险的原因之一,它是一个传递到
FixedFormatter
的过程,只能与
FixedLocator
一起使用。我还建议将定位器重新设置为
MaxNLocator
,并传递
integer=True
(或对现有的一个进行修改),以确保不会出现类似
[1.0、1.25、1.5、1.75、2.0]的滴答声
哪一个会将前4个标记为“b”。这非常有用,您是否愿意加入PR,将其添加到mpl库中?当然。增加了拉动请求#5063。