Matplotlib - 在x轴上调整日期间距

时间:2015-05-10 02:00:16

标签: python matplotlib

我的数据如下:

print x

        Date       ABC       DEF
0 2004-06-03  1.000000  1.000000
1 2004-06-04  1.000000  1.007940
2 2004-06-07  1.000000  1.023285
3 2004-06-08  1.020163  1.024712
4 2004-06-09  1.013932  1.015166

我正在以下列方式进行策划:

plt.figure()
x.plot().set_xticklabels(x['Date'])
plt.show()

我的问题是x轴刻度太紧而无意义。

我怎样才能得到每个N周期都显示在x轴上?

另外 - 如果您知道答案 - 我如何将x轴上的数字格式化为日期?

谢谢!

1 个答案:

答案 0 :(得分:1)

编辑:代码中的所有评论都已添加以便澄清。

我将展示两个回答这两个问题的例子。我根据你发布的样本数据制作了一个小csv。

这是一个只显示日期的情节:

import pandas as pd
import matplotlib.pyplot as plt
import datetime as dt
import numpy as np
import math

# the sample data provided in the question was made into a csv and read in using pandas
data = pd.read_csv('Workbook1.csv', sep=',')
# get just the 'Date' column
dates = data['Date']

"""
datetime is a python module to work with dates, time, timezones, time differences

strptime(date_string, format) method is used to read in a string (which we know is
a date) and return a datetime. e.g.

>>> s = '2015-05-11'
>>> dt.datetime.strptime(s, '%Y-%m-%d')
datetime.datetime(2015, 5, 11, 0, 0)

>>> print dt.datetime.strptime(s, '%Y-%m-%d')
2015-05-11 00:00:00

>>> print dt.datetime.strptime(s, '%Y-%m-%d').date()
2015-05-11

list comprehension: a way to create a list

create a list of integers from 0 to 9:
>>> [x for x in range(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

create a list of 1/n! for n from 0 to 99 and sum the values:
>>> sum( [1.0/math.factorial(n) for n in xrange(100)] )
2.7182818284590455

below we use list comprehension to map date strings to datetimes in the 
specified format YYYY-MM-DD
"""
dates = [dt.datetime.strptime(d,'%Y-%m-%d').date() for d in dates]

现在绘图:

""" 
we want to plot multiple data columns on one plot, so we use the layout 
manager subplots().  if we wanted to break out individual plots for each 
data source we could use subplots(n, m, o) where n,m,o are ints defining 
the layout.
figure is the window our plot will reside in
ax is used for nearly everything else: plot itself, labels, ticks, 
ticklabels, title(s)"""

fig, ax = plt.subplots()
# plot 'ABC' column, using red (r) line and label 'ABC' which is used in the legend
ax.plot(data['ABC'],'r-',label='ABC')
ax.plot(data['DEF'],'b-',label='DEF')
# set the number of ticks on x-axis to be a list [0, ... ,R]
# R is the number of rows in the data (i.e. len(dates))
# this ensures ticklabels align with the corresponding data point
ax.set_xticks(np.arange(len(dates))) 
ax.set_xticklabels(dates)     # set the ticklabels to the list of datetimes
ax.legend(loc=4, fontsize=10) # make a legend and place in bottom-right (loc=4)
plt.xticks(rotation=30)       # rotate the xticklabels by 30 deg
plt.show()

enter image description here

所以这个情节只显示日期。如果这仍然过于局促,您还可以将日期格式更改为m / d / y,也可以跳过每个第N个xticklabel。查看变量spacing并根据需要进行设置。

# using the list of datetimes from above make a list of strings with specific
# format.  datetime.strftime(format) returns a string in the specified format
short_dates = [d.strftime('%m/%d/%y') for d in dates]

spacing = 2
fig, ax = plt.subplots()
ax.plot(data['ABC'],'r-',label="ABC")
ax.plot(data['DEF'],'b-',label='DEF')
ax.set_xticks(np.arange(len(short_dates)))
ax.set_xticklabels(short_dates)
ax.legend(loc=4, fontsize=10)
plt.xticks(rotation=30)
# for each label in the list of xticklabels 
# (we skip every n'th label in this list using [::n]):
# set to not visible
for label in ax.xaxis.get_ticklabels()[::spacing]:
    label.set_visible(False)
plt.show()

enter image description here

现在日期格式已更改,我们正在跳过其他所有日期(来自给定数据)。希望这会有所帮助。

This是一个很棒的matplotlib教程。