Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.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 datetime x轴matplotlib标签导致不受控制的重叠_Python_Pandas_Matplotlib - Fatal编程技术网

Python datetime x轴matplotlib标签导致不受控制的重叠

Python datetime x轴matplotlib标签导致不受控制的重叠,python,pandas,matplotlib,Python,Pandas,Matplotlib,我正试图用一个'pandas.tseries.index.DatetimeIndex'来绘制一个pandas系列。x轴标签顽固地重叠,我无法使它们看起来像样,即使有几种建议的解决方案 我试过了,但没用 我还尝试了plt.tight_layout()的建议,但没有效果 ax = test_df[(test_df.index.year ==2017) ]['error'].plot(kind="bar") ax.figure.autofmt_xdate() #plt.tight_layout() p

我正试图用一个
'pandas.tseries.index.DatetimeIndex'
来绘制一个pandas
系列。x轴标签顽固地重叠,我无法使它们看起来像样,即使有几种建议的解决方案

我试过了,但没用

我还尝试了
plt.tight_layout()
的建议,但没有效果

ax = test_df[(test_df.index.year ==2017) ]['error'].plot(kind="bar")
ax.figure.autofmt_xdate()
#plt.tight_layout()
print(type(test_df[(test_df.index.year ==2017) ]['error'].index))

更新:我正在使用条形图是一个问题。常规时间序列图显示管理良好的标签


在您的情况下,最简单的方法是手动创建标签和间距,并使用
ax.xaxis.set\u major\u formatter
应用它们

下面是一个可能的解决方案:

由于没有提供样本数据,我尝试在带有一些随机数的数据框中模拟数据集的结构

设置:

# imports
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import matplotlib.ticker as ticker

# A dataframe with random numbers ro run tests on
np.random.seed(123456)
rows = 100
df = pd.DataFrame(np.random.randint(-10,10,size=(rows, 1)), columns=['error'])
datelist = pd.date_range(pd.datetime(2017, 1, 1).strftime('%Y-%m-%d'), periods=rows).tolist()
df['dates'] = datelist 
df = df.set_index(['dates'])
df.index = pd.to_datetime(df.index)

test_df = df.copy(deep = True)

# Plot of data that mimics the structure of your dataset
ax = test_df[(test_df.index.year ==2017) ]['error'].plot(kind="bar")
ax.figure.autofmt_xdate()
plt.figure(figsize=(15,8))

可能的解决方案:

test_df = df.copy(deep = True)
ax = test_df[(test_df.index.year ==2017) ]['error'].plot(kind="bar")
plt.figure(figsize=(15,8))

# Make a list of empty myLabels
myLabels = ['']*len(test_df.index)

# Set labels on every 20th element in myLabels
myLabels[::20] = [item.strftime('%Y - %m') for item in test_df.index[::20]]
ax.xaxis.set_major_formatter(ticker.FixedFormatter(myLabels))
plt.gcf().autofmt_xdate()

# Tilt the labels
plt.setp(ax.get_xticklabels(), rotation=30, fontsize=10)
plt.show()


通过选中“条形图”是分类图,可以轻松更改标签的格式。它在刻度上的整数位置为每个索引显示一个条。因此,第一个条位于位置0,下一个条位于位置1等。标签对应于数据帧的索引。如果你有100个条,你将得到100个标签。这是有意义的,因为熊猫不知道这些数据应该被视为类别还是顺序/数字数据

如果改为使用普通matplotlib条形图,它将以数字方式处理数据帧索引。这意味着条形图的位置与实际日期一致,标签的位置与自动售票机的位置一致

import pandas as pd
import numpy as np; np.random.seed(42)
import matplotlib.pyplot as plt

datelist = pd.date_range(pd.datetime(2017, 1, 1).strftime('%Y-%m-%d'), periods=42).tolist()
df = pd.DataFrame(np.cumsum(np.random.randn(42)), 
                  columns=['error'], index=pd.to_datetime(datelist))

plt.bar(df.index, df["error"].values)
plt.gcf().autofmt_xdate()
plt.show()

这样做的好处是,还可以使用
matplotlib.dates
定位器和格式化程序。例如,使用自定义格式标记每个月的第一个月和第十五个月

import pandas as pd
import numpy as np; np.random.seed(42)
import matplotlib.pyplot as plt
import matplotlib.dates as mdates

datelist = pd.date_range(pd.datetime(2017, 1, 1).strftime('%Y-%m-%d'), periods=93).tolist()
df = pd.DataFrame(np.cumsum(np.random.randn(93)), 
                  columns=['error'], index=pd.to_datetime(datelist))

plt.bar(df.index, df["error"].values)
plt.gca().xaxis.set_major_locator(mdates.DayLocator((1,15)))
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter("%d %b %Y"))
plt.gcf().autofmt_xdate()
plt.show()

从图中可以看出这种方法的问题。您使用月份标签标记一个月内的一些任意日期,这会导致
“2017-01”
在某个随机位置出现两次。同意。你的建议已经有了我的upvote=)我喜欢我自己的建议的地方是在标签的密集度以及标签字符串的格式方面的灵活性。哦,也许我的回答不清楚,但是更改位置和格式的灵活性正是使用数字轴的优势。我更新了它,使它变得更清晰。我不知道。很不错的!