如何使用 matplotlib 在日期时间轴上绘制一个矩形?

Posted

技术标签:

【中文标题】如何使用 matplotlib 在日期时间轴上绘制一个矩形?【英文标题】:How to plot a rectangle on a datetime axis using matplotlib? 【发布时间】:2015-09-18 16:43:06 【问题描述】:

我尝试使用以下代码在带有日期时间 x 轴的图表上绘制一个矩形:

from datetime import datetime, timedelta
from matplotlib.patches import Rectangle
import matplotlib.pyplot as plt

# Create new plot
fig = plt.figure()
ax = fig.add_subplot(111)

# Create rectangle
startTime = datetime.now()
width = timedelta(seconds = 1)
endTime = startTime + width
rect = Rectangle((startTime, 0), width, 1, color='yellow')

# Plot rectangle
ax.add_patch(rect)   ### ERROR HERE!!! ###
plt.xlim([startTime, endTime])
plt.ylim([0, 1])
plt.show()

但是,我得到了错误:

TypeError: unsupported operand type(s) for +: 'float' and 'datetime.timedelta'

怎么了? (我使用的是 matplotlib 1.0.1 版)

【问题讨论】:

【参考方案1】:

您在尝试使用 x 的日期时间值创建 patches.Rectangle 艺术家时看到的另一个错误是:

TypeError: float() argument must be a string or a number.

原因是在Rectangle对象初始化期间x参数在内部被转换为float:

self._x = float(xy[0])

它不适用于日期时间值。 @hitzg 提出的解决方案将解决这个问题,因为 matplotlib.dates.date2num() 返回浮点数。

【讨论】:

【参考方案2】:

问题在于 matplotlib 使用自己的日期/时间表示(浮动天数),因此您必须先转换它们。此外,您必须告诉 xaxis 它应该有日期/时间刻度和标签。下面的代码就是这样做的:

from datetime import datetime, timedelta
from matplotlib.patches import Rectangle
import matplotlib.pyplot as plt
import matplotlib.dates as mdates

# Create new plot
fig = plt.figure()
ax = fig.add_subplot(111)

# Create rectangle x coordinates
startTime = datetime.now()
endTime = startTime + timedelta(seconds = 1)

# convert to matplotlib date representation
start = mdates.date2num(startTime)
end = mdates.date2num(endTime)
width = end - start

# Plot rectangle
rect = Rectangle((start, 0), width, 1, color='yellow')
ax.add_patch(rect)   

# assign date locator / formatter to the x-axis to get proper labels
locator = mdates.AutoDateLocator(minticks=3)
formatter = mdates.AutoDateFormatter(locator)
ax.xaxis.set_major_locator(locator)
ax.xaxis.set_major_formatter(formatter)

# set the limits
plt.xlim([start-width, end+width])
plt.ylim([-.5, 1.5])

# go
plt.show()

结果:

注意:Matplotlib 1.0.1 非常旧。我不能保证我的例子会奏效。你应该尝试更新!

【讨论】:

注意,如果x轴的日期来自pandas,则需要先转换为python date-time。那么start = mdates.date2num( startTime ) 行将是start = mdates.date2num( startTime.to_pydatetime() )end 也是如此。【参考方案3】:

问题是type(startTime) datetime.datetime 不是传递到矩形的有效类型。需要将其类型转换为支持的类型才能使用矩形补丁。

如果您真正想要的是制作一个黄色矩形,只需制作一个带有黄色背景的普通图:

from datetime import datetime, timedelta
from matplotlib.patches import Rectangle
import matplotlib.pyplot as plt

# Create new plot
fig = plt.figure()
ax = fig.add_subplot(111, axisbg='yellow')
plt.xticks(rotation=15)
plt.tight_layout()
# Create rectangle
startTime = datetime.now()
width = timedelta(seconds = 1)
endTime = startTime + width

#rect = Rectangle((0, 0), 1, 1, color='yellow')

# Plot rectangle
#ax.add_patch(rect)   ### ERROR HERE!!! ###

plt.xlim([startTime, endTime])
plt.ylim([0, 1])
plt.show()

【讨论】:

以上是关于如何使用 matplotlib 在日期时间轴上绘制一个矩形?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 python 中使用 matplotlib 和 pandas 绘制 CSV 数据

在 matplotlib 中更改日期时间轴的格式

在 matplotlib 中绘制熊猫日期

Python matplotlib - 如何在x轴上绘制一条线?

使用 Matplotlib 在 x 轴上的月份名称偏移

使用 PyQtGraph 绘制 Datetime 对象