#python #pandas #matplotlib #bar-chart #yaxis
#python #панды #matplotlib #гистограмма #yaxis
Вопрос:
У меня есть фрейм данных из 6 столбцов, которые я хочу отобразить в виде гистограммы. Последние 3 столбца находятся на вторичной оси. Один из последних 3 столбцов имеет значения с гораздо более высоким масштабом, чем два других, и я хотел бы добавить 3-ю ось Y, чтобы отобразить ее в соответствующем масштабе. В следующем примере кода мне удалось добавить одну дополнительную ось Y. Но я не смог найти способ добавить дополнительную (3-ю) ось Y.
Вот пример кода:
# %config IPCompleter.greedy=True
import pandas as pd
import matplotlib.pyplot as plt
# Set the plotting settings
plotStyleDict = {'axes.titlesize' : 18,
'axes.titleweight' :'bold',
'axes.labelsize' : 15,
'lines.linewidth' : 3,
'lines.markersize' : 10,
'xtick.labelsize' : 12,
'ytick.labelsize' : 12}
plt.style.use(plotStyleDict)
dataDict = {'Year': ['1st Year','2st Year','3rd Year','4th Year'],
'ERRh': [0, 0.71, 0.46, 0.35],
'HRRh': [0.0, 0.66, 0.33, 0.14],
'EREh': [0.0, 0.38, 0.20, 0.11],
'ERRc': [1.2, 1.62, 2.04, 0.04],
'HRRc': [1.36, 2.27, 4.83, 0.09],
'EREc': [150, 120, 90, 70]}
# Create a dataframe
dfDataTest=pd.DataFrame.from_dict(dataDict, orient='columns', dtype=None, columns=None)
# Set Year column as index
dfDataTest.index = dfDataTest.Year
# delete Year column
dfDataTest.drop('Year', inplace = True, axis=1)
# To rename df columns with Greek symbols to be easier to show them as legends on the plot
orig_cols = ['ERRh', 'HRRh','EREh','ERRc', 'HRRc', 'EREc']
rename_cols = [r'$eta_{ER,h}$', r'$eta_{HR,h}$', r'$eta_{th,h}$',r'$eta_{ER,c}$',
r'$eta_{HR,c}$',r'$eta_{th,c}$']
rename_dict = dict(zip(orig_cols, rename_cols))
# Bar plot the dataframe with last 3 columns being on secondary axis
ax1FunEnergy = dfDataTest [orig_cols].rename(columns=rename_dict).
plot(kind='bar',color=['firebrick','red', 'darksalmon','darkblue','blue','royalblue'],
figsize=(16,6), edgecolor=['black','black','black','black','black','black'],
stacked=False, secondary_y= [r'$eta_{ER,c}$', r'$eta_{HR,c}$',r'$eta_{th,c}$'])
plt.xticks(rotation=30, horizontalalignment="center")
plt.title("Energy amp; Hydraulic Recoveries for Heating and Cooling",fontsize=18, weight='bold')
ax1FunEnergy.set_ylabel(r'$eta_{ER,h} , eta_{HR,h} , eta_{th,h} [-]$')
ax1FunEnergy.right_ax.set_ylabel(r'$eta_{ER,c} , eta_{HR,c} , eta_{th,c} [-]$')
plt.grid(True)
plt.show()
Это приводит к следующему графику:
Масштаб последнего столбца слишком велик по сравнению с остальными. Таким образом, два других столбца, построенных на вторичной оси Y, едва видны. Итак, мои вопросы заключаются в следующем:
- Есть ли способ добавить дополнительную (3-ю) ось Y к гистограмме для построения последнего столбца?
- Если это возможно, как переместить имя последнего столбца из метки вторичной оси Y в метку 3-й оси Y, сохранив при этом другие параметры построения, такие как цвет полосы, края и т.д.?
- Как я могу указать все ограничения по оси Y и размер и вес шрифта по оси y?
Заранее спасибо! 🙂
Комментарии:
1. В руководстве по matplotlib есть очень поучительный пример того, как создавать паразитные оси .
Ответ №1:
Для графиков pandas сложно создавать сложные графики, поэтому я создал график с общим matplotlib, чтобы добавить третью ось.
import numpy as np
fig,ax = plt.subplots(figsize=(16,6))
labels = dfDataTest.index.tolist()
x = np.arange(len(labels))
ax2 = ax.twinx()
ax3 = ax.twinx()
ax.set_xlim(-0.5, 4)
ax.set_ylim(0, 1)
ax2.set_ylim(0, 5)
ax3.set_ylim(0,160)
ax.set_xlabel('Year')
ax.set_ylabel(r'$eta_{ER,h} , eta_{HR,h} , eta_{th,h} [-]$', size=18)
ax2.set_ylabel(r'$eta_{ER,h} , eta_{HR,h} , eta_{th,h} [-]$', size=18)
ax3.set_ylabel(r'$eta_{ER,c} , eta_{HR,c} , eta_{th,c} [-]$', size=18)
color=['firebrick','red','darksalmon','darkblue','blue','royalblue']
width = 0.1
p1 = ax.bar(x-(width*3), dfDataTest['ERRh'], width=width, color=color[0], align='center', label=r'$eta_{ER,h}$')
p2 = ax.bar(x-(width*2), dfDataTest['HRRh'], width=width, color=color[1], align='center', label=r'$eta_{ER,h}$')
p3 = ax.bar(x-width, dfDataTest['EREh'], width=width, color=color[2], align='center', label=r'$eta_{ER,h}$')
p4 = ax2.bar(x, dfDataTest['ERRc'], width=width, color=color[3], align='center', label=r'$eta_{HR,h}, eta_{th,h}$')
p5 = ax2.bar(x (width*1), dfDataTest['HRRc'], width=width, color=color[4], align='center', label=r'$eta_{HR,h}, eta_{th,h}$')
p6 = ax3.bar(x (width*2), dfDataTest['EREc'], width=width, color=color[5], align='center', label=r'$eta_{ER,c} , eta_{HR,c}$')
lns = [p1,p2,p3,p4,p5,p6]
ax.legend(handles=lns, loc='best')
ax3.spines['right'].set_position(('outward', 60))
ax3.xaxis.set_ticks([])
ax.set_xticks(x)
ax.set_xticklabels(labels)
ax.set_title("Energy amp; Hydraulic Recoveries for Heating and Cooling",fontsize=18, weight='bold')
ax3.set_ylabel(r'$eta_{ER,c} , eta_{HR,c} , eta_{th,c} [-]$')
fig.show()