Python / Matplotlib-按年份的日期直方图 [英] Python / Matplotlib -- Histogram of Dates by Day of Year

查看:629
本文介绍了Python / Matplotlib-按年份的日期直方图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个跨越数(百)年的日期列表。我想制作一个直方图,该直方图包含366个桶,一年中的每一天,并以清晰易懂的方式标记x轴,这样我就可以看到哪个日期是哪个日期(我希望2月29日有所下降(例如)。


我制作了以下直方图,但是易于阅读的X轴日期标签会很棒。下面的代码看起来很麻烦,但是却得到了我想要的东西(没有X轴标签):

  from datetime导入日期,datetime,timedelta $ b来自集合导入的$ b导入计数器
导入pylab


def plot_data(data):
数据是包含字段的字典的列表日期带有日期时间。

def get_day(d):
return d.strftime(%B%d)#例如1月1日

天= []
n = 366
start_date = date(2020,1,1)#为i在范围(n)中选择a年

d =开始日期+ timedelta(days = i)
days.append(get_day(d))

counts = d的Counter(get_day(d ['date']))在数据中)

Y = [counts.get(d)for d in days]
X = list(range(len(day(days))))

pylab .bar(X,Y)
pylab.xlim([0,n])

pylab.title(一年中的日期)
pylab.xlabel( ;每年的天数(0-366))
pylab.ylabel(计数)
pylab.savefig(图1.png)


任何有助于缩短时间和




UPDATE 将使x轴日期更灵活,更清晰! g>


我已将以下构想整合到

解决方案

尝试检查此代码:

 #import section 
进口熊猫为pd
进口matplotlib.pyplot为plt
进口matplotlib.dates为md
进口numpy为np
从日期时间进口日期
从itertools进口产品

#生成一个像您一样的数据框
date = [date(2020,m,d).strftime(%B%d)for product(range(1, 13,1),range(1,29,1))]
value = np.abs(np.random.randn(len(date)))
data = pd.DataFrame({'date ':date,
'value':value})
data.set_index ('date',inplace = True)

#将索引从str转换为日期
data.index = pd.to_datetime(data.index,format ='%B%d')

#绘制
图,ax = plt.subplots(1,1,figsize =(16,8))
ax.bar(data.index,
data ['value'])

#格式化xaxis
ax.xaxis.set_major_locator(md.DayLocator(interval = 5))
ax.xaxis.set_major_formatter(md.DateFormatter( '%B%d'))
plt.setp(ax.xaxis.get_majorticklabels(),旋转= 90)
ax.set_xlim([data.index [0],data.index [-1 ]])

plt.show()





我转换了数据帧的索引从字符串到日期,然后我通过 ax.xaxis.set_major_locator ax.xaxis.set_major_formatter 方法。

为了绘图,我使用了 matplotlib ,但是将这种方法转换为 pylab






编辑



如果您想要几天和几个月的单独刻度,可以添加辅助轴(选中此


I have a list of dates that span several (hundred) years. I'd like to make a histogram that has 366 buckets, one for each day of the year, with the x-axis labelled in a legible way that allows me to see which date is which (I'm expecting a dip for February 29, for example).

I've made the following histogram, but easy-to-read X-axis date labels would be awesome. The following code seems cumbersome but gets me what I want (without the X-axis labels):

from datetime import date, datetime, timedelta
from collections import Counter
import pylab


def plot_data(data):
    """data is a list of dicts that contain a field "date" with a datetime."""

    def get_day(d):
        return d.strftime("%B %d")  # e.g. January 01

    days = []
    n = 366
    start_date = date(2020, 1, 1)  # pick a leap year
    for i in range(n):
        d = start_date + timedelta(days=i)
        days.append(get_day(d))

    counts = Counter(get_day(d['date']) for d in data)
    
    Y = [counts.get(d) for d in days]
    X = list(range(len(days)))

    pylab.bar(X, Y)
    pylab.xlim([0, n])

    pylab.title("Dates day of year")
    pylab.xlabel("Day of Year (0-366)")
    pylab.ylabel("Count")
    pylab.savefig("Figure 1.png")

Any help to shorten this up and make for more flexible and legible x-axis dates would be much appreciated!


UPDATE

I've incorporated the ideas below into the following gist, which produces output that looks like this:

解决方案

Try to check this code:

# import section
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as md
import numpy as np
from datetime import date
from itertools import product

# generate a dataframe like yours
date = [date(2020, m, d).strftime("%B %d") for m, d in product(range(1, 13, 1), range(1, 29, 1))]
value = np.abs(np.random.randn(len(date)))
data = pd.DataFrame({'date': date,
                     'value': value})
data.set_index('date', inplace = True)

# convert index from str to date
data.index = pd.to_datetime(data.index, format = '%B %d')

# plot
fig, ax = plt.subplots(1, 1, figsize = (16, 8))
ax.bar(data.index,
       data['value'])

# formatting xaxis
ax.xaxis.set_major_locator(md.DayLocator(interval = 5))
ax.xaxis.set_major_formatter(md.DateFormatter('%B %d'))
plt.setp(ax.xaxis.get_majorticklabels(), rotation = 90 )
ax.set_xlim([data.index[0], data.index[-1]])

plt.show()

that gives me this plot:

I converted the index of the dataframe from string to date, then I applied the xaxis format that I want through ax.xaxis.set_major_locator and ax.xaxis.set_major_formatter methods.
In order to plot that I used matplotlib, but it should not be difficult to translate this approach to pylab.


EDIT

If you want days and months of separate ticks, you can add a secondary axis (check this example) as in this code:

# import section
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as md
import numpy as np
from datetime import date
from itertools import product
from mpl_toolkits.axes_grid1 import host_subplot
import mpl_toolkits.axisartist as AA

# generate a dataframe like yours
date = [date(2020, m, d).strftime("%B %d") for m, d in product(range(1, 13, 1), range(1, 29, 1))]
value = np.abs(np.random.randn(len(date)))
data = pd.DataFrame({'date': date,
                     'value': value})
data.set_index('date', inplace = True)

# convert index from str to date
data.index = pd.to_datetime(data.index, format = '%B %d')

# prepare days and months axes
fig = plt.figure(figsize = (16, 8))
days = host_subplot(111, axes_class = AA.Axes, figure = fig)
plt.subplots_adjust(bottom = 0.1)
months = days.twiny()

# position months axis
offset = -20
new_fixed_axis = months.get_grid_helper().new_fixed_axis
months.axis['bottom'] = new_fixed_axis(loc = 'bottom',
                                       axes = months,
                                       offset = (0, offset))
months.axis['bottom'].toggle(all = True)

#plot
days.bar(data.index, data['value'])

# formatting days axis
days.xaxis.set_major_locator(md.DayLocator(interval = 10))
days.xaxis.set_major_formatter(md.DateFormatter('%d'))
plt.setp(days.xaxis.get_majorticklabels(), rotation = 0)
days.set_xlim([data.index[0], data.index[-1]])

# formatting months axis
months.xaxis.set_major_locator(md.MonthLocator())
months.xaxis.set_major_formatter(md.DateFormatter('%b'))
months.set_xlim([data.index[0], data.index[-1]])

plt.show()

which produces this plot:

这篇关于Python / Matplotlib-按年份的日期直方图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆