So, on this graph: I want the "Margem EBITDA" bar to be alongside the other two bars that are on top of each other. I did some research and most answers suggested displacing it with numbers, but since my x-ticks are strings, I'd have to a whole workaround for plotting with numbers and then replacing the ticks, which I really don't want to do. Here's the code:
meses=['Fevereiro/21', 'Março/21', 'Abril/21']
faturamentor=[498899.40, 623122.74, 653200.18]
faturamento=[499, 623, 653]
gasto=[65, 130, 188]
margem=[84.7, 76.6, 69.5]
locale.setlocale(locale.LC_ALL, 'pt_BR.UTF-8')
seaborn.set()
seaborn.set_style("white")
plt.rcParams["figure.figsize"] = (19,10)
plt.rcParams["font.family"] = "Calibri"
plt.rc('font', size=14)
plt.rc('axes', labelsize=20)
plt.rc('xtick', labelsize=15)
plt.rc('ytick', labelsize=15)
plt.rc('legend', fontsize=15)
ax = plt.subplot(111)
ax.bar(meses, faturamento, width=0.3, color='#434343', align='center', label='Faturamento líquido')
ax.bar(meses, gasto, width=0.3, color='#999999', align='center', label='Gasto em anúncios')
ax.grid(axis='y')
ax.set_ylabel('Valor (milhares de reais)')
for i in range(len(faturamento)):
plt.annotate(xy=(i, faturamento[i]+10), text=f'R${faturamentor[i]:n}', ha='center', va='center', color='#434343')
plt.legend()
plt.xlabel('Mês')
plt.ylim(0, faturamento[-1]+(0.1*faturamento[-1]))
ax2 = ax.twinx()
ax2.set_ylabel('Margem EBITDA (%)')
ax2.bar(meses, margem, label="Margem EBITDA", color='#cccccc', width=0.1)
ax2.tick_params(axis='y', labelcolor='k')
ax2.set_ylim(20, 92)
ax2.set_yticks([20, 30, 40, 50, 60, 70, 80, 90])
plt.legend()
fig1 = plt.gcf()
plt.show()
Thanks for your help! EDIT: While we're at it, how could I make labels for both axes appear on the same box?
You can use np.linspace
to distribute the available space over the bars. With ax.get_legend_handles_labels()
you can extract the legend information, and create a new legend with the combined information:
from matplotlib import pyplot as plt
import numpy as np
import seaborn
meses = ['Fevereiro/21', 'Março/21', 'Abril/21']
faturamentor = [498899.40, 623122.74, 653200.18]
faturamento = [499, 623, 653]
gasto = [65, 130, 188]
margem = [84.7, 76.6, 69.5]
seaborn.set()
seaborn.set_style("white")
plt.rcParams["figure.figsize"] = (19, 10)
plt.rcParams["font.family"] = "Calibri"
plt.rc('font', size=14)
plt.rc('axes', labelsize=20)
plt.rc('xtick', labelsize=15)
plt.rc('ytick', labelsize=15)
plt.rc('legend', fontsize=15)
num_meses = len(meses)
num_bars = 3
tot_width = .8
dodge = np.linspace(-tot_width / 2, tot_width / 2, num_bars + 1)
width = dodge[1] - dodge[0]
ax = plt.subplot(111)
ax.set_xticks(np.arange(num_meses))
ax.set_xticklabels(meses)
ax.bar(np.arange(num_meses) + dodge[0], faturamento, width=width,
color='#434343', align='edge', label='Faturamento líquido')
ax.bar(np.arange(num_meses) + dodge[1], gasto, width=width,
color='#999999', align='edge', label='Gasto em anúncios')
ax.grid(axis='y')
ax.set_ylabel('Valor (milhares de reais)')
for xpos, faturamento_i in zip(np.arange(num_meses) + dodge[0], faturamento):
ax.annotate(xy=(xpos+width/2, faturamento_i), text=f'R${faturamento_i:n}\n', ha='center', va='center', color='#434343')
ax.set_xlabel('Mês')
ax.set_ylim(0, faturamento[-1] + (0.1 * faturamento[-1]))
ax2 = ax.twinx()
ax2.set_ylabel('Margem EBITDA (%)')
ax2.bar(np.arange(num_meses) + dodge[2], margem, label="Margem EBITDA", color='#cccccc', width=width, align='edge')
ax2.tick_params(axis='y', labelcolor='k')
ax2.set_ylim(20, 92)
ax2.set_yticks([20, 30, 40, 50, 60, 70, 80, 90])
handles1, labels1 = ax.get_legend_handles_labels()
handles2, labels2 = ax2.get_legend_handles_labels()
ax.legend(handles=handles1 + handles2, labels=labels1 + labels2)
plt.show()