在Matplotlib中使用datetime作为刻度

时间:2016-02-17 19:02:07

标签: python datetime numpy matplotlib

我基本上试图绘制一个图表,其中x轴代表一年中的月份。数据存储在numpy.array中,维度为k x months。这是一个最小的例子(我的数据不是很疯狂):

import numpy
import matplotlib
import matplotlib.pyplot as plt

cmap = plt.get_cmap('Set3')
colors = [cmap(i) for i in numpy.linspace(0, 1, len(complaints))]

data = numpy.random.rand(18,12)
y = range(data.shape[1])

plt.figure(figsize=(15, 7), dpi=200)
for i in range(data.shape[0]):
    plt.plot(y, data[i,:], color=colors[i], linewidth=5)
plt.legend(loc='center left', bbox_to_anchor=(1, 0.5)) 
plt.xticks(numpy.arange(0, 12, 1))
plt.xlabel('Hour of the Day')
plt.ylabel('Number of Complaints')
plt.title('Number of Complaints per Hour in 2015')

enter image description here

我想将xticks作为字符串而不是数字。我想知道是否必须手动创建字符串列表,或者是否有其他方式将数字翻译数月。例如,我必须在工作日也这样做。

我一直在寻找这些例子:

http://matplotlib.org/examples/pylab_examples/finance_demo.html http://matplotlib.org/examples/pylab_examples/date_demo2.html

但我没有使用datetime

3 个答案:

答案 0 :(得分:7)

这是另一种绘图方法plot_date,如果您的自变量为datetime,则可能需要使用该方法,而不是使用更通用的plot方法:

import datetime
data = np.random.rand(24)

#a list of time: 00:00:00 to 23:00:00
times = [datetime.datetime.strptime(str(i), '%H') for i in range(24)]

#'H' controls xticklabel format, 'H' means only the hours is shown
#day, year, week, month, etc are not shown
plt.plot_date(times, data, fmt='H')
plt.setp(plt.gca().xaxis.get_majorticklabels(),
         'rotation', 90)

enter image description here

它的好处是,现在您可以轻松控制xticks的密度,如果我们想要每小时打勾,我们将在plot_date之后插入这些行:

##import it if not already imported
#import matplotlib.dates as mdates
plt.gca().xaxis.set_major_locator(mdates.HourLocator())

enter image description here

答案 1 :(得分:2)

您仍然可以使用格式化程序以您希望的方式格式化结果。例如,要打印月份名称,让我们首先定义一个整数到月份缩写的函数:

def getMonthName(month_number):
    testdate=datetime.date(2010,int(month_number),1)
    return testdate.strftime('%b')

在这里,我创建了一个具有正确月份的任意日期并返回该月份。如果需要,请检查the datetime documentation以获取可用的格式代码。如果这总是比手工设置列表更容易是另一个问题。现在让我们绘制一些每月测试数据:

import matplotlib.pyplot as plt
import matplotlib.ticker as mtick
import numpy as np

x_data=np.arange(1,12.5,1)
y_data=x_data**2 # Just some arbitrary data
plt.plot(x_data,y_data)
plt.gca().xaxis.set_major_locator(mtick.FixedLocator(x_data)) # Set tick locations
plt.gca().xaxis.set_major_formatter(mtick.FuncFormatter(lambda x,p:getMonthName(x)))
plt.show()

此处的消息是您可以使用matplotlib.ticker.FuncFormatter使用任何函数来获取刻度标签。该函数接受两个参数(值和位置)并返回一个字符串。

答案 2 :(得分:0)

虽然this answer效果很好,但在这种情况下,您可以避免使用FuncFormatter中的预定义日期来定义自己的matplotlib,而使用matplotlib.datesmatplotlib.ticker

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

# Define time range with 12 different months:
# `MS` stands for month start frequency 
x_data = pd.date_range('2018-01-01', periods=12, freq='MS') 
# Check how this dates looks like:
print(x_data)
y_data = np.random.rand(12)
fig, ax = plt.subplots()
ax.plot(x_data, y_data)
# Make ticks on occurrences of each month:
ax.xaxis.set_major_locator(mdates.MonthLocator())
# Get only the month to show in the x-axis:
ax.xaxis.set_major_formatter(mdates.DateFormatter('%b'))
# '%b' means month as locale’s abbreviated name
plt.show()

获取:

DatetimeIndex(['2018-01-01', '2018-02-01', '2018-03-01', '2018-04-01',
           '2018-05-01', '2018-06-01', '2018-07-01', '2018-08-01',
           '2018-09-01', '2018-10-01', '2018-11-01', '2018-12-01'],
          dtype='datetime64[ns]', freq='MS')

Plot showing abbreviated months on the x-axis