2015-07-01 18 views
9

Tôi cố gắng để vẽ một hình chữ nhật trên một đồ thị với một datetime trục x bằng cách sử dụng đoạn mã sau:Làm thế nào để vẽ một hình chữ nhật trên trục datetime bằng cách sử dụng matplotlib?

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() 

Tuy nhiên, tôi nhận được lỗi:

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

gì đang xảy ra vậy? (Tôi đang sử dụng phiên bản matplotlib 1.0.1)

Trả lời

10

Vấn đề là matplotlib sử dụng đại diện riêng của mình ngày/lần (số nổi của ngày), vì vậy bạn phải chuyển đổi chúng trước tiên. Hơn nữa, bạn sẽ phải nói với xaxis rằng nó nên có ngày/thời gian ve và nhãn. Đoạn code dưới đây làm thế:

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() 

Kết quả:

enter image description here

LƯU Ý: Matplotlib 1.0.1 là rất cũ. Tôi không thể đảm bảo rằng ví dụ của tôi sẽ hoạt động. Bạn nên cố gắng cập nhật!

+0

Lưu ý rằng nếu các ngày trong trục x là từ 'pandas', bạn cần phải chuyển đổi thành ngày giờ trăn đầu tiên. Dòng 'start = mdates.date2num (startTime)' sẽ là 'start = mdates.date2num (startTime.to_pydatetime())'. Điều tương tự cũng xảy ra với 'kết thúc'. – Luis

-1

Vấn đề là type(startTime) datetime.datetime không phải là loại hợp lệ để chuyển vào hình chữ nhật. Nó cần phải được gõ vào một loại được hỗ trợ để sử dụng các miếng vá hình chữ nhật.

Nếu tất cả các bạn thực sự muốn là để tạo ra một hình chữ nhật màu vàng chỉ làm cho một âm mưu bình thường với một nền màu vàng:

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() 
0

Một lỗi mà bạn có thể thấy khi cố gắng để tạo ra một nghệ sĩ patches.Rectangle sử dụng các giá trị datetime cho x là:

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

Lý do cho điều này là trong Rectangle đối tượng khởi x luận được chuyển đổi trong nội bộ để float:

self._x = float(xy[0])

Nó không làm việc cho d giá trị giờ. Giải pháp được đề xuất bởi @hitzg sẽ giải quyết vấn đề này vì matplotlib.dates.date2num() trả về phao.

Các vấn đề liên quan