5

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

4
  • 1
    I cannot reproduce this. your code works for me (OSX; panda version: 0.16.2; matplotlib version: 1.4.3) Commented Aug 4, 2015 at 17:27
  • @DizietAsahi I'm running Anaconda 2.3, Windows 7 64-bit. Running this in an ipython notebook with %matplotlib inline. sorry should have clarified. Commented Aug 5, 2015 at 9:32
  • "Thanks to @DizietAsahi - Found out that this is a problem with DatetimeIndex as x-values." - Give them an upvote, then ;) On a serious note - rather than putting the edit in the question - it would be better to write your own answer referencing DizietAsahi answer and accept it, or edit the link to pandas issue you raised into his answer. Otherwise, the question shows as unanswered. [Self answers](stackoverflow.com/help/self-answer) are perfectly fine on here. Commented Aug 10, 2015 at 12:02
  • @JRichardSnape - Done! thanks for the tip. I thought I already upvoted his answer! Commented Aug 10, 2015 at 12:40

3 Answers 3

6

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

Sign up to request clarification or add additional context in comments.

2 Comments

tried this but didn't solve my problem. Let me do some more tests and come back, thanks!
Found out why I couldn't get your results. The issue happens when I have a DatetimeIndex for the data frame. for your code, if you try: drange = pd.date_range(start='2015-07-01', end='2015-07-10', freq='D'); df = pd.DataFrame(data=np.random.random_sample((10, 3)), index=drange, columns=['col1', 'col2', 'col3']); It will reproduce my problem if you plot it with your code above even with plt.hold(True)..
6

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

Comments

1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.