WillZ
WillZ

Reputation: 3965

Python Pandas DataFrame - Cannot plot bars and lines on the same axes

I might be doing something wrong but I'm struggling to achieve the below:

# plot bars and lines in the same figure, sharing both x and y axes.
df = some DataFrame with multiple columns
_, ax = plt.subplots()
df[col1].plot(kind='bar', ax=ax)
df[col2].plot(ax=ax, marker='o', ls='-')
ax.legend(loc='best')

I expected to see a chart with both some bars and a line. However, what I end up with is only the line for df[col2], the bars from df[col1] are just not on the chart. Whatever is before df[col2] seem to have been overwritten.

I got around this with:

df[col1].plot(kind='bar', ax=ax, label=bar_labels)
ax.plot(df[col2], marker='o', ls='-', label=line_labels)
ax.legend(loc='best')

However, this isn't perfect as I had to use label tags otherwise legends will not included items for df[col2]...

Anyone out there has a more elegant solution to make both bars and lines show up?

** Edit ** Thanks to @DizietAsahi - Found out that this is a problem with DatetimeIndex as x-values. Filed the following at Pandas:

https://github.com/pydata/pandas/issues/10761#issuecomment-128671523

Upvotes: 5

Views: 2994

Answers (3)

Dùn Caan
Dùn Caan

Reputation: 111

I have the same problem with using DatetimeIndex as my x-values. I couldn't get the hack at github to work, using Jupyter Notebook Version 4.2.0 with Python 2.7.11. I'm grouping two columns by month to plot as bars, then overlaying raw values as a line graph.

My solution is to use matplotlib to plot the bar charts and the line, this was the only way I could get it to work.

import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
matplotlib.style.use('ggplot')
%matplotlib inline

df = pd.read_excel('data.xlsx', index_col='Date')
fig, ax = plt.subplots(figsize=(15,10)) 
ax.hold(True)
g = df.groupby(pd.TimeGrouper("M"))
width=10

ax.bar(g.sum().index, g['Money Out'].sum(),width=width, color='r',label='Money Out')
ax.bar(g.sum().index, g['Money in'].sum(),width=-width,color='g', label='Money In')
ax.plot(df[['Balance']], color='black', lw=1, ls='-',label='Balance')  

ax.legend(loc='best')

image

Upvotes: 1

WillZ
WillZ

Reputation: 3965

Thanks to @DizietAsahi - Found out that this is a problem with DatetimeIndex as x-values. Integer values work with @DizietAsahi's code above.

Filed the following at Pandas:

https://github.com/pydata/pandas/issues/10761#issuecomment-128671523

Upvotes: 6

Diziet Asahi
Diziet Asahi

Reputation: 40697

I wonder if your problem is related to the hold state of your plot...

This works:

df = pd.DataFrame(np.random.random_sample((10,2)), columns=['col1', 'col2'])
fig, ax = plt.subplots()
plt.hold(True)
df['col1'].plot(kind='bar', ax=ax)
df['col2'].plot(ax=ax, marker='o', ls='-')
ax.legend(loc='best')

enter image description here

This only shows the line and not the bar plot

df = pd.DataFrame(np.random.random_sample((10,2)), columns=['col1', 'col2'])
fig, ax = plt.subplots()
plt.hold(False)
df['col1'].plot(kind='bar', ax=ax)
df['col2'].plot(ax=ax, marker='o', ls='-')
ax.legend(loc='best')

enter image description here

Upvotes: 6

Related Questions