Python 如何使用Matplotlib'从错误栏创建框;x轴使用datetime对象时的Patch集合?

Python 如何使用Matplotlib'从错误栏创建框;x轴使用datetime对象时的Patch集合?,python,matplotlib,Python,Matplotlib,Matplotlib提供了有关“”的示例。 在这里的示例之后,我想实现该示例中给出的make_error_box()函数,用于图形的x轴显示日期(即,它使用python的datetime对象)而不是整数或浮点数 如何修改生成错误框()函数 import numpy as np import matplotlib.pyplot as plt from matplotlib.collections import PatchCollection from matplotlib.patches impo

Matplotlib提供了有关“”的示例。 在这里的示例之后,我想实现该示例中给出的
make_error_box()
函数,用于图形的x轴显示日期(即,它使用python的
datetime
对象)而不是整数或浮点数

如何修改
生成错误框()
函数

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import PatchCollection
from matplotlib.patches import Rectangle
from datetime import datetime, timedelta, timezone

def make_error_boxes( ax, xdata, ydata, xerror, yerror, facecolor='r',
                      edgecolor='None', alpha=0.5 ):

    # Loop over data points; create box from errors at each point
    errorboxes = [Rectangle( (x-xe, y-ye), xe*2, ye*2 )
               for x, y, xe, ye in zip(xdata, ydata, xerror, yerror)]

    # Create patch collection with specified colour/alpha
    pc = PatchCollection(errorboxes, facecolor=facecolor, alpha=alpha,
                         edgecolor=edgecolor)

    # Add collection to axes
    ax.add_collection(pc)


fig, ax = plt.subplots( 1,1 )
days = np.arange( 10 )
dates = [ datetime.today() + timedelta( days=day.tolist() ) for day in days ]
y = [9, 9, 9, 9, 9, 9, 9, 8, 8, 8 ] 
xerr = [timedelta( days=0.5 ) for day in days] #TypeError: float() argument must be a string or a number, not 'datetime.datetime'
#xerr = [ 1 for day in days] #TypeError: unsupported operand type(s) for -: 'datetime.datetime' and 'float'
yerr = [3.75, 1.7, 2.5, .5, 1.1, 1.5, 3., 2., 1., .5]
ax.errorbar( dates, y, yerr=yerr,label='Median')

make_error_boxes( ax, dates, y, xerr, yerr ) 
                  
plt.legend(loc='upper right')
plt.show()

1。使用Matplotlib日期

Python的
datetime
对象需要是,它使用浮点数来指定天数。此转换可以使用函数完成。1天的震级似乎为1.0

2。使用matplotlib.dates日期标记定位器和格式设置器显示matplotlib日期。

3。修订稿:

我的脚本应该修改为:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from matplotlib.dates import MO, TU, WE, TH, FR, SA, SU
from matplotlib.collections import PatchCollection
from matplotlib.patches import Rectangle
from datetime import datetime, timedelta, timezone

def make_error_boxes( ax, xdata, ydata, xerror, yerror, facecolor='r',
                      edgecolor='None', alpha=0.5 ):

    # Loop over data points; create box from errors at each point
    errorboxes = [ Rectangle( (x-xe, y-ye), xe*2, ye*2 )
                   for x, y, xe, ye in zip(xdata, ydata, xerror, yerror) ]

    # Create patch collection with specified colour/alpha
    pc = PatchCollection(errorboxes, facecolor=facecolor, alpha=alpha,
                         edgecolor=edgecolor)

    # Add collection to axes
    ax.add_collection(pc)


fig, ax = plt.subplots( 1,1 )
days = np.arange( 10 )
dates = [ datetime.today() + timedelta( days=day.tolist() ) for day in days ]
mpdates = [ mdates.date2num(date) for date in dates ]
y = [9, 9, 9, 9, 9, 9, 9, 8, 8, 8 ] 
xhalfmag = ( mpdates[1] -mpdates[0] ) * 0.5
xerr = [ xhalfmag for _ in mpdates]
yerr = [3.75, 1.7, 2.5, .5, 1.1, 1.5, 3., 2., 1., .5]

ax.errorbar( mpdates, y, yerr=yerr, label='Median' )
make_error_boxes( ax, mpdates, y, xerr, yerr )

fig.autofmt_xdate() # rotate and align the tick labels so they look better. From https://matplotlib.org/3.1.3/gallery/recipes/common_date_problems.html
ax.xaxis.set_major_locator( mdates.WeekdayLocator( byweekday=(MO, TU, WE, TH, FR, SA, SU), interval=1, tz=None ) )
ax.xaxis.set_major_formatter( mdates.DateFormatter("%b %d %a", tz=None) )
                  
plt.legend(loc='upper right')
plt.show()