2012-06-14 18 views
6

en el código siguiente, BDate y EDATE son tanto datetime.datetime() Objetos:¿Cómo puedo usar xaxis_date() con barh()?

pylab.barh(ypos, edate - bdate, left=bdate, height=TRMWidth) 

pero esto arroja una AttributeError camino hacia abajo en dates.py._to_ordinalf():

File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/pyplot.py", line 1926, in barh ret = ax.barh(bottom, width, height, left, **kwargs) File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/axes.py", line 4774, in barh orientation='horizontal', **kwargs) File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/axes.py", line 4624, in bar width = self.convert_xunits(width) File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/artist.py", line 147, in convert_xunits return ax.xaxis.convert_units(x) File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/axis.py", line 1312, in convert_units ret = self.converter.convert(x, self.units, self) File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/dates.py", line 1125, in convert return date2num(value) File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/dates.py", line 260, in date2num else: return np.asarray([_to_ordinalf(val) for val in d]) File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/dates.py", line 189, in _to_ordinalf base = float(dt.toordinal())

AttributeError: 'datetime.timedelta' object has no attribute 'toordinal'

i pensé que sería genial si pudiera meter fechas en xaxis y tenerlo resolver los detalles; no tanto. ¿Alguna sugerencia sobre cómo hacer que las fechas sean accesibles para xaxis?

Respuesta

11

Lo que está sucediendo es que matplotlib en realidad no usa objetos datetime para trazar.

Las fechas se convierten primero en formato de punto flotante interno. La conversión no está configurada para manejar timedeltas (que es posiblemente un descuido).

Básicamente, puedes hacer exactamente lo que quieres, solo tienes que convertir explícitamente las fechas al formato interno de matplotlib primero, y luego llamar al ax.xaxis_date().

Como un ejemplo rápido (mayor parte de esta es la generación de datos para trazar ...):

import datetime as dt 
import matplotlib.pyplot as plt 
import matplotlib.dates as mdates 

def drange(start, end, interval=dt.timedelta(days=1)): 
    output = [] 
    while start <= end: 
     output.append(start) 
     start += interval 
    return output 

# Generate a series of dates for plotting... 
edate = drange(dt.datetime(2012, 2, 1), dt.datetime(2012, 6, 15), 
         dt.timedelta(days=5)) 
bdate = drange(dt.datetime(2012, 1, 1), dt.datetime(2012, 5, 15), 
         dt.timedelta(days=5)) 

# Now convert them to matplotlib's internal format... 
edate, bdate = [mdates.date2num(item) for item in (edate, bdate)] 

ypos = range(len(edate)) 
fig, ax = plt.subplots() 

# Plot the data 
ax.barh(ypos, edate - bdate, left=bdate, height=0.8, align='center') 
ax.axis('tight') 

# We need to tell matplotlib that these are dates... 
ax.xaxis_date() 

plt.show() 

enter image description here

Cuestiones relacionadas