matplotlib | TypeError: unsupported operand type(s) for -: 'Timestamp' and 'float'

Question:

How can I draw a FancyBboxPatch on a plot with a date x-axis. The FancyBboxPatch should stretch over a specific time period, similar to a gantt chart.

import matplotlib.pyplot as plt
import pandas as pd

data = [('2019-04-15', 'Start'), ('2019-05-01', 'Stop')]
date, labels = zip(*data)
frame = pd.DataFrame({'bla': labels}, index=pd.DatetimeIndex(date))

fig, ax = plt.subplots(figsize=(12.5, 2.5))

for index, row in frame.iterrows():

    ax.text(index, 0.5, row['bla'])

ax.set_xlim([frame.index[0], frame.index[-1]])

plt.show()

enter image description here

I tried to copy and paste and adjust code from the Matplotlib website. However, this caused errors which were related to the date axis and the width of the patch.

Update

I tried with the code below. However, it returns TypeError: unsupported operand type(s) for -: 'Timestamp' and 'float'.

import matplotlib.pyplot as plt
import pandas as pd
import matplotlib.patches as mpatches

data = [('2019-04-15', 'Start'), ('2019-05-01', 'Stop')]
date, labels = zip(*data)
frame = pd.DataFrame({'bla': labels}, index=pd.DatetimeIndex(date))

fig, ax = plt.subplots(figsize=(12.5, 2.5))

for index, row in frame.iterrows():

    ax.text(index, 0.5, row['bla'])

ax.set_xlim([frame.index[0], frame.index[-1]])

ax.add_patch(
    mpatches.FancyBboxPatch(
        (frame.index[0],0.5),  # xy
        100,  # width
        0.5,  # heigth
        boxstyle=mpatches.BoxStyle("Round", pad=0.02)
        )
    )

plt.show()
Asked By: Stücke

||

Answers:

You can try using matplotlib.dates.date2num(d) from here to convert your datetime objects to Matplotlib dates like this:

import matplotlib.pyplot as plt
import pandas as pd
import matplotlib.patches as mpatches
import matplotlib.dates as dates

data = [('2019-04-15', 'Start'), ('2019-05-01', 'Stop')]
date, labels = zip(*data)
frame = pd.DataFrame({'bla': labels}, index=pd.DatetimeIndex(date))

print(f'frame.index[0] {frame.index[0]}')

fig, ax = plt.subplots(figsize=(12.5, 2.5))

for index, row in frame.iterrows():

    ax.text(index, 0.5, row['bla'])

ax.set_xlim([frame.index[0], frame.index[-1]])

ax.add_patch(
    mpatches.FancyBboxPatch(
        (dates.date2num(frame.index[0]),0.5),  # Conversion
        100,  # width
        0.5,  # heigth
        boxstyle=mpatches.BoxStyle("Round", pad=0.02)
        )
    )

plt.show()
Answered By: The Singularity
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.