I am working with Matplotlib and trying to plot a combo box with bars and lines. Below you can see my data:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.cm import get_cmap
from matplotlib.ticker import FormatStrFormatter
# Data
data = {
'Year': ['2010','2011','2012','2013','2014','2015','2016','2017','2018','2019'],
'Rate':[10,10,9,7,5,5,5,5,5,5],
'ChangeRate_1':[7,-50,24,150,8,10,60,5,180,5],
'ChangeRate_2':[7,6,-3,1,8,5,8,5,15,5],
}
df = pd.DataFrame(data, columns = ['Year',
'Rate',
'ChangeRate_1',
'ChangeRate_2'
])
df
Below you can see code :
# Ploting combo plot
fig, ax_1 = plt.subplots(figsize = (8, 5))
ax_2 = ax_1.twinx()
ax_3 = ax_2.twinx() ### <---- Problem is probably here
cmap = get_cmap('tab10')
ax_1.bar(df['Year'], df['Rate'], label = 'Rate', color = cmap(0))
ax_2.plot(df['Year'], df['ChangeRate_1'], label = 'ChangeRate_2', color = cmap(0.1),linewidth = '3.5')
ax_3.plot(df['Year'], df['ChangeRate_2'], label = 'ChangeRate_2', color = cmap(0.2),linewidth = '3.5')
handles_1, labels_1 = ax_1.get_legend_handles_labels()
handles_2, labels_2 = ax_2.get_legend_handles_labels()
handles_3, labels_3 = ax_3.get_legend_handles_labels()
ax_1.set_ylim(0, 16)
ax_2.set_ylim(-50,180)
ax_1.legend(handles = handles_1 handles_2 labels_3,
labels = labels_1 labels_2 labels_3,
loc = 'upper right',
shadow = True)
ax_1.grid(axis = 'y')
ax_1.set_title('Comparison of revenues',fontsize=11)
ax_1.set_ylabel('Rate')
ax_2.set_ylabel('ChangeRate_1')
ax_3.set_ylabel('ChangeRate_2')
ax_1.xaxis.set_major_formatter(FormatStrFormatter('%.0f'))
plt.savefig('ComparisonOfRevenues.pdf')
plt.show()
The above code produces a plot that is shown below.
As shown in the above plot, values for the y-axis
for the left and for the right side overlap with values and are not readable.
For the left side, the scale for the 'Rate' should be in the range of 0 to 16, while for the right side, for ChangeRate_1 and ChangeRate_2, from -50 to 180.
So can anybody help me how to solve this problem ?
CodePudding user response:
The instantiation of the third Axes object with ax_3 = ax_2.twinx()
can be circumvented by using just one extra y-axis on the right and plotting ChangeRate_1
and ChangeRate_2
on that axis keeping the (right) y-axis label as ChangeRate
and then assigning correct labels to the lines.
Code:
fig, ax_1 = plt.subplots(figsize=(8, 5))
ax_2 = ax_1.twinx()
cmap = get_cmap('tab10')
ax_1.bar(df['Year'], df['Rate'], label='Rate', color=cmap(0))
ax_2.plot(df['Year'], df['ChangeRate_1'], label='ChangeRate_1', color=cmap(0.1), linewidth='3.5')
ax_2.plot(df['Year'], df['ChangeRate_2'], label='ChangeRate_2', color=cmap(0.2), linewidth='3.5')
handles_1, labels_1 = ax_1.get_legend_handles_labels()
handles_2, labels_2 = ax_2.get_legend_handles_labels()
ax_1.set_ylim(0, 16)
ax_2.set_ylim(-50,180)
ax_1.legend(handles=handles_1 handles_2, labels=labels_1 labels_2,
loc='upper right', shadow=True)
ax_1.grid(axis='y')
ax_1.set_title('Comparison of revenues',fontsize=11)
ax_1.set_ylabel('Rate')
ax_2.set_ylabel('ChangeRate')
ax_1.xaxis.set_major_formatter(FormatStrFormatter('%.0f'))
plt.show()