I trying to plot a stacked area graph using matplotlib with vertical line(s) on top. My MWE is:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# my data
df = pd.DataFrame(data={'date': pd.date_range(start='2020-09-01', freq='D', periods=100),
'x1': np.random.randint(80,200,size=100),
'x2': np.random.randint(50,90,size=100),
'x3': np.random.randint(50,100,size=100),
})
df = df.set_index('date')
df0 = df.query("index == 20201026") # points of interest
fig = plt.figure()
ax = fig.add_subplot(111)
df.plot(ax=ax, kind='area')
ax.vlines(df0.index, ymin=0, ymax=1000, color='k', lw=1)
# ax.vlines(pd.concat([df0,df0], axis=0).index, ymin=0, ymax=1000, color='k', lw=1, ls='--')
ax.set_ylim((0,400))
ax.legend(loc='lower right')
plt.show()
The area graph is plotted using df
and any point(s) of interest are in df0
. If there is just one point in df0
, when I plot using vlines
I get an error
TypeError: ufunc 'isfinite' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''
But if I use pd.concat([df0,df0], axis=0)
, there's no problem with vlines
. Why does this happen? I can't find anything in the docs that say vlines
must accept more than one vertical line.
CodePudding user response:
Matplotlib doesn't know how to deal with pd.Index
. Use tolist
to solve the problem:
ax.vlines(df0.index.tolist(), ymin=0, ymax=1000, color='k', lw=1)
# HERE ---^
Solution proposed by @BigBen:
# HERE ---v
df.plot(ax=ax, kind='area', x_compat=True)
ax.vlines(df0.index, ymin=0, ymax=1000, color='k', lw=1)