matplotlib.dates(和datestr2num)的图表刻度中的日期格式问题 [英] Date format issues in plot ticks with matplotlib.dates (and datestr2num)

查看:155
本文介绍了matplotlib.dates(和datestr2num)的图表刻度中的日期格式问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 matplotlib.dates 绘制一个条形图,其中包含发生在特定日期的实例(以字符串列表的形式显示),并使用 matplotlib.dates.datestr2num 显示每个日期的两组数据(根据顶部调用

I'm using matplotlib.dates to plot a bar chart with instances occurring on specific dates (presented as a list of strings), and using matplotlib.dates.datestr2num to display two sets of data per date (as per the top answer in Python matplotlib multiple bars).

However, for dates below the 12th day of the month, the plot is interpreting the dates in MM/DD/YY format, while for dates above the 12th day of the month it is interpreting the dates as DD/MM/YY, causing the data to jump around the plot. I think the issue might be in how I'm using datestr2num, but not sure how to force it to be in one format or another.

import matplotlib.pyplot as plt
from matplotlib.dates import DateFormatter, AutoDateLocator, AutoDateFormatter, datestr2num

days = ['30/01/2019', '31/01/2019', '01/02/2019', '02/02/2019', '03/02/2019', '04/02/2019']
adata = [1, 9, 10, 3, 7, 6]
bdata = [1, 2, 11, 3, 6, 2]

x=datestr2num(days)

w=0.25
fig = plt.figure(figsize = (8,4))
ax = fig.add_subplot(111)
ax.bar(x-w, adata, width=2*w, color='g', align='center', tick_label = days)
ax.bar(x+w, bdata, width=2*w, color='r', align='center', tick_label = days)
ax.xaxis_date()
ax.xaxis.set_major_locator(AutoDateLocator(minticks=3, interval_multiples=False))
ax.xaxis.set_major_formatter(DateFormatter("%d/%m/%y"))

plt.show()

In the example above, adata and bdata are on subsequent dates (30th Jan to 4th Feb), with all the bars shown as next to each other but the plot displays the data between the 2nd of Jan and the 2nd of Apr, making the data appear out of order.

Any help or clarifiaction would be helpful, thanks!

解决方案

It appears that datestr2num() calls dateutil.parser.parse(d, default=default). dateutil.parser.parse has a kwarg dayfirst but datestr2num() does not provide a way to pass the argument forward. If you pass a list of dates to datesttr2num() it will assume month first.

>>> [dateutil.parser.parse(day, dayfirst=True) for day in days]
[
    datetime.datetime(2019, 1, 30, 0, 0), 
    datetime.datetime(2019, 1, 31, 0, 0), 
    datetime.datetime(2019, 2, 1, 0, 0), 
    datetime.datetime(2019, 2, 2, 0, 0), 
    datetime.datetime(2019, 2, 3, 0, 0), 
    datetime.datetime(2019, 2, 4, 0, 0)
]

>>> datestr2num(days)
[737089. 737090. 737061. 737092. 737120. 737151.]

>>> datestr2num(days, dayfirst=True)
Traceback (most recent call last):
File "C:\Users\bcohan\Downloads\so.py", line 22, in <module>
    print(datestr2num(days, dayfirst=True))
TypeError: datestr2num() got an unexpected keyword argument 'dayfirst'

I would suggest processing the dates with datetime first and then running the rest. (Unless it's reasonable to rewrite the strings in the original days list.)

x = datestr2num([
    datetime.strptime(day, '%d/%m/%Y').strftime('%m/%d/%Y')
    for day in days
])

Here is a fully working script.

from datetime import datetime
import matplotlib.pyplot as plt
from matplotlib.dates import (
    DateFormatter, AutoDateLocator, AutoDateFormatter, datestr2num
)

days = [
    '30/01/2019', '31/01/2019', '01/02/2019',
    '02/02/2019', '03/02/2019', '04/02/2019'
]
adata = [1, 9, 10, 3, 7, 6]
bdata = [1, 2, 11, 3, 6, 2]

x = datestr2num([
    datetime.strptime(day, '%d/%m/%Y').strftime('%m/%d/%Y')
    for day in days
])
w = 0.25

fig = plt.figure(figsize=(8, 4))
ax = fig.add_subplot(111)
ax.bar(x - w, adata, width=2 * w, color='g', align='center', tick_label=days)
ax.bar(x + w, bdata, width=2 * w, color='r', align='center', tick_label=days)
ax.xaxis_date()
ax.xaxis.set_major_locator(
    AutoDateLocator(minticks=3, interval_multiples=False))
ax.xaxis.set_major_formatter(DateFormatter("%d/%m/%y"))

plt.show()

这篇关于matplotlib.dates(和datestr2num)的图表刻度中的日期格式问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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