I have a DataFrame
that contains price/volume data on an intraday basis:
time price volume
2015-04-15 10:10:00 10 500
2015-04-15 10:20:00 15 100
2015-04-15 10:30:00 20 70
2015-04-15 10:30:00 etc etc
I need to get a standard price - volume chart, where the top chart contains the prices (a regular line), and the bottom chart contains the volume (a bar chart).
Both charts should share the same axis, of course.
So far, I have come up with:
plt.figure(figsize=(20,15))
ax1=plt.subplot2grid((2,2),(0,0),colspan=2)
ax2=plt.subplot2grid((2,2),(1,0),colspan=2)
ax2.xaxis.set_major_locator(HourLocator(interval=3))
ax2.xaxis.set_major_formatter(DateFormatter('%H:%M'))
data.ix['2015-10-01': '2015-10-02','price'].plot(ax=ax1)
data.ix['2015-10-01': '2015-10-02','volume'].plot(ax=ax2, kind='bar')
But I get super-dense tick labels for the bar charts (the chart is unusable).
How can I simply specify to have minor ticks every hours, and major ticks every 3 hours (so that the chart is still readable)?
There are some challenges with pandas.plot.bar()
and DateTimeIndex
that are discussed for instance here. The following:
import matplotlib as mpl
import matplotlib.pyplot as plt
plt.style.use('ggplot')
import pandas as pd
import numpy as np
from datetime import datetime
n = 100
idx = pd.date_range(start=datetime(2016, 1, 1, 10), freq='10Min', periods=n)
data = pd.DataFrame(data={'price': np.cumsum([0.0001] * n + np.random.random(n)),
'volume': np.random.randint(low=100, high=10000, size=n)}, index=idx)
fig, ax = plt.subplots(nrows=2, sharex=True, figsize=(15,8))
ax[0].plot(data.index, data.price)
ax[1].bar(data.index, data.volume, width=1/(5*len(data.index)))
xfmt = mpl.dates.DateFormatter('%H:%M')
ax[1].xaxis.set_major_locator(mpl.dates.HourLocator(interval=3))
ax[1].xaxis.set_major_formatter(xfmt)
ax[1].xaxis.set_minor_locator(mpl.dates.HourLocator(interval=1))
ax[1].xaxis.set_minor_formatter(xfmt)
ax[1].get_xaxis().set_tick_params(which='major', pad=25)
fig.autofmt_xdate()
plt.show()
produces the below result. Notice that falling back to matplotlib
requires some fiddling with the width
parameter in ax[1].bar()
. For minorticks
, you may want to look here for more detailed formatting options, esp. re skipping intervals to avoid overlap.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With