【问题标题】:Using datetime as ticks in Matplotlib在 Matplotlib 中使用日期时间作为刻度
【发布时间】:2016-05-29 16:06:34
【问题描述】:

我基本上是在尝试绘制一个图表,其中 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')

我想将xticks 作为字符串而不是数字。我想知道是否必须手动创建一个字符串列表,或者是否有另一种方法可以将数字翻译到月份。例如,我必须在工作日做同样的事情。

我一直在寻找这些例子:

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

但我没有使用datetime。

【问题讨论】:

    标签: python datetime numpy matplotlib


    【解决方案1】:

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

    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】:

      这是另一种绘图方法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)
      

      它的好处是现在你可以轻松控制xticks的密度,如果我们想每小时有一个tick,我们将在plot_date之后插入这些行:

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

      【讨论】:

      • 感谢您指出 plot_date() 方法。仅当您在 x 数据中已有四舍五入的小时数时,这才有效吗?我正在使用的数据没有,并且使用 mdate.HourLocator() 最终根本没有刻度标签。
      【解决方案3】:

      虽然this answer 效果很好,但在这种情况下,您可以避免定义自己的FuncFormatter,方法是使用matplotlib 中的预定义日期,使用matplotlib.dates 而不是matplotlib.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')
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-06-25
        • 2016-01-03
        • 1970-01-01
        • 1970-01-01
        • 2018-11-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多