我必须用很高的x值密度绘制几条曲线,比如1000个日期字符串。为了防止这些刻度标签相互重叠,我手动将它们设置为60个日期。代码如下:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
ts_index = pd.period_range(start="20060429", periods=1000).strftime("%Y%m%d")
fig = plt.figure(1)
ax = plt.subplot(1, 1, 1)
tick_spacing = 60
for i in range(5):
plt.plot(ts_index, 1 + i * 0.01 * np.arange(0, 1000), label="group %d"%i)
plt.legend(loc='best')
plt.title(r'net value curves')
xticks = ax.get_xticks()
xlabels = ax.get_xticklabels()
ax.set_xticks(xticks[::tick_spacing])
ax.set_xticklabels(xlabels[::tick_spacing])
plt.xticks(rotation="vertical")
plt.xlabel(r'date')
plt.ylabel('net value')
plt.grid(True)
plt.show()
fig.savefig(r".\net_value_curves.png", )
fig.clf()我正在使用Python3.6内核在PyCharm Community 2017.2.2中运行这段代码。现在有趣的是:每当我以正常的“运行”模式运行代码(即按下“执行”按钮,让代码“自由”运行,直到中断或终止),那么我得到的数据总是会错过xticklabels:

但是,如果我以“调试”模式运行代码并一步一步地运行它,那么我将得到一个包含完整xticklabels的预期数字:

这真的很奇怪。无论如何,我只是希望找到一种方法,可以确保我在正常的“运行”模式下获得所需的输出(第二个数字)。如何修改当前代码以实现此目的?
提前感谢!
发布于 2018-03-15 10:34:36
您的x轴数据是字符串。因此,每个数据点将得到一个滴答。这可能不是你想要的。相反,请使用日期来绘制图。因为你用的是熊猫,这很容易转化,
dates = pd.to_datetime(ts_index, format="%Y%m%d")然后,您可以摆脱手动的x抽签定位和格式化,因为matplotlib将自动为您选择一些不错的滴答位置。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
ts_index = pd.period_range(start="20060429", periods=1000).strftime("%Y%m%d")
dates = pd.to_datetime(ts_index, format="%Y%m%d")
fig, ax = plt.subplots()
for i in range(5):
plt.plot(dates, 1 + i * 0.01 * np.arange(0, 1000), label="group %d"%i)
plt.legend(loc='best')
plt.title(r'net value curves')
plt.xticks(rotation="vertical")
plt.xlabel(r'date')
plt.ylabel('net value')
plt.grid(True)
plt.show()

但是,如果您确实希望手动控制位置和格式,则可以使用matplotlib.dates定位器和格式化程序。
# tick every 3 months
plt.gca().xaxis.set_major_locator(mdates.MonthLocator((1,4,7,10)))
# format as "%Y%m%d"
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter("%Y%m%d"))

发布于 2018-03-15 07:53:42
通常,Axis对象使用Locator对象计算并放置滴答。Locators和Formatters是很容易替换的,具有适当的方法 of Axis。默认的Locator似乎没有为您发挥作用,因此您可以使用axes.xaxis.set_major_locator来替换它。这个问题不足以编写您自己的问题,因此我建议MaxNLocator非常适合您的需要。您的例子似乎很适合nbins=16 (这是图片中的内容,因为有17条滴答。
您需要添加一个导入:
from matplotlib.ticker import MaxNLocator你需要换掉那个块
xticks = ax.get_xticks()
xlabels = ax.get_xticklabels()
ax.set_xticks(xticks[::tick_spacing])
ax.set_xticklabels(xlabels[::tick_spacing])使用
ax.xaxis.set_major_locator(MaxNLocator(nbins=16))或者只是
ax.xaxis.set_major_locator(MaxNLocator(16))您可能希望使用其他参数(除了nbins之外,所有参数都必须是关键字)。特别注意integer。
注意,对于Locator和Formatter API,我们使用的是Axis对象,而不是Axes。Axes是整个情节,而Axis是上面有刺的东西。Axes通常包含两个Axis对象和绘图中的所有其他内容。
发布于 2018-03-15 02:27:59
您可以将xticks标签的可见性设置为False。
for label in plt.gca().xaxis.get_ticklabels()[::N]:
label.set_visible(False)这将使每一个第N标签不可见。
https://stackoverflow.com/questions/49290456
复制相似问题