2
votes

When creating bar graphs and line graphs using matplotlib via pandas I've come across some inconsistent behaviour. For example:

import matplotlib.pyplot as plt
import pandas as pd
from pandas_datareader import data

test_df = data.get_data_yahoo('AAPL', start='2015-10-01')
test_df['Adj Close'].plot()

Plots as expected with sensible x axis labels:

enter image description here

However if you then try to plot something from the same dataframe as a bar graph:

test_df['Volume'].plot(kind='bar')

enter image description here

The x axis tick labels are no longer automatically sensible.

Is this intended behaviour of pandas/matplotlib? And how can one easily rectify the x axis tick labels on bar graphs to be similar to the one in the line graph above?

1

1 Answers

3
votes

You could tell matplotlib to show every Nth label:

# show every Nth label
locs, labels = plt.xticks()
N = 10
plt.xticks(locs[::N], test_df.index[::N].strftime('%Y-%m-%d'))

import matplotlib.pyplot as plt
import pandas as pd
from pandas_datareader import data

test_df = data.get_data_yahoo('AAPL', start='2015-10-01')
fig, ax = plt.subplots(nrows=2)
test_df['Adj Close'].plot(ax=ax[0])
test_df['Volume'].plot(kind='bar', ax=ax[1])

# show every Nth label
locs, labels = plt.xticks()
N = 10
plt.xticks(locs[::N], test_df.index[::N].strftime('%Y-%m-%d'))

# autorotate the xlabels
fig.autofmt_xdate()
plt.show()

yields enter image description here


Another option is to use matplotlib directly:

import matplotlib.pyplot as plt
import pandas as pd
from pandas_datareader import data
import matplotlib.dates as mdates

df = data.get_data_yahoo('AAPL', start='2015-10-01')
fig, ax = plt.subplots(nrows=2, sharex=True)

ax[0].plot(df.index, df['Adj Close'])
ax[0].set_ylabel('price per share')

ax[1].bar(df.index, df['Volume']/10**6)
ax[1].xaxis.set_major_locator(mdates.MonthLocator(bymonthday=-1))
xfmt = mdates.DateFormatter('%B %d, %Y')
ax[1].xaxis.set_major_formatter(xfmt)
ax[1].set_ylabel('Volume (millions)')

# autorotate the xlabels
fig.autofmt_xdate()
plt.show()

enter image description here