Plot Pandas Dataframe as Bar and Line on the Same One Chart

Plot Pandas DataFrame as Bar and Line on the same one chart

The DataFrame plotting methods return a matplotlib AxesSubplot or list of AxesSubplots. (See the docs for plot, or boxplot, for instance.)

You can then pass that same Axes to the next plotting method (using ax=ax) to draw on the same axes:

ax = df_13_14_target[['month','2014_target_val']].plot(x='month',linestyle='-', marker='o')
df_13_14_target[['month','2013_val','2014_val']].plot(x='month', kind='bar',
ax=ax)

import pandas as pd
import matplotlib.pyplot as plt

left_2013 = pd.DataFrame(
{'month': ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep',
'oct', 'nov', 'dec'],
'2013_val': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 6]})

right_2014 = pd.DataFrame({'month': ['jan', 'feb'], '2014_val': [4, 5]})

right_2014_target = pd.DataFrame(
{'month': ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep',
'oct', 'nov', 'dec'],
'2014_target_val': [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]})

df_13_14 = pd.merge(left_2013, right_2014, how='outer')
df_13_14_target = pd.merge(df_13_14, right_2014_target, how='outer')

ax = df_13_14_target[['month', '2014_target_val']].plot(
x='month', linestyle='-', marker='o')
df_13_14_target[['month', '2013_val', '2014_val']].plot(x='month', kind='bar',
ax=ax)

plt.show()

Sample Image

pandas DataFrame how to mix bar and line plots with different scales

Does this solve your problem?

fig, ax = plt.subplots()
ax2 = ax.twinx()
ax.bar(df_eg.index, df_eg["Release"], color=(190/255,190/255,190/255,0.7), label='Release')
ax2.plot(df_eg.index, df_eg["Hold"], color='green', label='Hold')
ax.set_xticklabels(df_eg.index)
ax.legend(loc='best')

Final Plot

Pandas plot bar chart over line

The main issue is that kinds="bar" plots the bars on the low end of the x-axis, (so 2001 is actually on 0) while kind="line" plots it according to the value given. Removing the x=["year"] just made it plot the value according to the order (which by luck matches your data precisely).

There might be a better way, but the quickest way I know would be to stop considering the year to be a number.

df = pd.DataFrame({'year':[2001,2002,2003,2004,2005], 'value':[100,200,300,400,500]})
df['value1']= df['value']*0.4
df['value2'] = df['value']*0.6
df['year'] = df['year'].astype("string") # Let them be strings!
fig, ax = plt.subplots(figsize = (15,8))
df.plot(x = ['year'], y = ['value'], kind = 'line', ax = ax)
df.plot(x = ['year'], y= ['value1','value2'], kind = 'bar', ax = ax)

Treating the year this way makes sense since you treat the year as a categorical data anyway, and the alphabetic order matches the numerical order.

Sample Image

Aligning line and bar charts in Python pandas

You can use reset_index to change the indexing of line dataframe back to start with zero.

This will allow your bars to line up with zero-based indexing like this:

ax_avg2 = df_bars.plot(kind = 'bar',
title = 'Average Daily Rainfall by Month',
ylabel = 'Average Daily Rainfall (mm)',
figsize = (10, 6)
)

df_means.reset_index().plot(
ax = ax_avg2,
kind = 'line',
y = 'Mean'
)

Output:

Sample Image

Pandas Graph Bar and Line plot problems

I can't be sure without seeing your data, but try running this instead of your code:

ax1 = CitySample2017.plot.bar(x='index', y='Town/City')
ax2 = ax1.twinx()
CitySample2017.plot(x='index', y='Population', ax=ax2)

Plotting lines and bars from pandas dataframe on same graph using matplotlib

A simple way would be to use the x_compat property:

ax = df.plot(x=index, y="A", x_compat=True)  # plot lines first
df.plot(x=index, y="B", kind="bar", ax=ax)

You can then adjust the tick frequency.

Hat-tip: https://stackoverflow.com/a/39907390/5276797



Related Topics



Leave a reply



Submit