Change axis x scale in a bar chart
Question:
I find myself graphing by means of bars a Dataframe that I have called barras
that contains data from 2017 to 2022, for months. In each month there are 3 columns with data denominated as % PRINCIPAL, % APORTES y % E
. I wanted to be able to graph the bars since 2009, even if there is no data, and that only the 1st and 6th months of each month appear on the x-axis labels, but I can’t do it.
This is the Dataframe:
% PRINCIPAL % APORTES % ΔE
FECHA
2017-03 25.974253 42.430129 31.595618
2017-04 131.728602 27.057582 -58.786184
2017-05 144.069530 17.564611 -61.634142
2017-06 116.492102 25.948196 -42.440299
2017-07 95.677079 42.383666 -38.060745
... ... ...
2022-05 86.728444 46.208640 -32.937084
2022-06 87.980394 58.643608 -46.624002
2022-07 73.873644 53.591839 -27.465483
2022-08 72.113597 44.375137 -16.488734
2022-09 52.777619 79.301887 -32.079506
And this is my code to do the graphic:
barras = pd.concat([I['% PRINCIPAL'],I['% APORTES'],I['% ΔE']], axis=1)
barras.index = pd.to_datetime(barras.index).strftime('%Y-%m')
barras.plot(kind="bar",stacked=True, color = ['b','g','r'], edgecolor='black', width=1, alpha=0.77, figsize=(16,8))
plt.title('PORCENTAJES DE CAUDAL EN TRAMO I')
plt.ylabel("Caudal (%)")
plt.xlabel('Fecha')
plt.legend(loc='best')
plt.savefig("BLOQUE I.png", bbox_inches="tight", dpi=160)
Result:
I want the same graphic but since 2009, and with the x-axis label each six moths.
I would like to get something like this (I’ve done it with photoshop):
Answers:
You can concatenate your dataframe with another one containing the rest of the dates you are interested in and then plot that.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# Create dummy data
dates = pd.date_range('2/2017', '8/2022', freq='M')
values = np.random.uniform(-100, 100, (len(dates), 3))
barras = pd.DataFrame(values, columns=['% PRINCIPAL', '% APORTES', '% ΔE'], index=dates)
# Create new dataframe with 0s for dates starting from 2009
add_dates = pd.date_range('1/2009', barras.index[0], freq='M')[:-1]
df_0 = pd.DataFrame(0, columns=['% PRINCIPAL', '% APORTES', '% ΔE'], index=add_dates)
# Concatenate everything into a single dataframe
barras = pd.concat([df_0, barras])
# Plot
fig, ax = plt.subplots(1,1, figsize=(16,8))
barras.set_index(barras.index.strftime('%Y-%m')).plot(
kind="bar",
stacked=True,
color = ['b','g','r'],
edgecolor='black',
width=1,
alpha=0.77,
ax=ax
)
new_ticks = ax.get_xticks()[barras.index.month.isin([1,1+6])]
ax.set_xticks(new_ticks)
plt.title('PORCENTAJES DE CAUDAL EN TRAMO I')
plt.ylabel("Caudal (%)")
plt.xlabel('Fecha')
plt.legend(loc='best')
plt.savefig("BLOQUE I.png", bbox_inches="tight", dpi=160)
EDIT: Now the code shows all the data and the temporal line is right.
I find myself graphing by means of bars a Dataframe that I have called barras
that contains data from 2017 to 2022, for months. In each month there are 3 columns with data denominated as % PRINCIPAL, % APORTES y % E
. I wanted to be able to graph the bars since 2009, even if there is no data, and that only the 1st and 6th months of each month appear on the x-axis labels, but I can’t do it.
This is the Dataframe:
% PRINCIPAL % APORTES % ΔE
FECHA
2017-03 25.974253 42.430129 31.595618
2017-04 131.728602 27.057582 -58.786184
2017-05 144.069530 17.564611 -61.634142
2017-06 116.492102 25.948196 -42.440299
2017-07 95.677079 42.383666 -38.060745
... ... ...
2022-05 86.728444 46.208640 -32.937084
2022-06 87.980394 58.643608 -46.624002
2022-07 73.873644 53.591839 -27.465483
2022-08 72.113597 44.375137 -16.488734
2022-09 52.777619 79.301887 -32.079506
And this is my code to do the graphic:
barras = pd.concat([I['% PRINCIPAL'],I['% APORTES'],I['% ΔE']], axis=1)
barras.index = pd.to_datetime(barras.index).strftime('%Y-%m')
barras.plot(kind="bar",stacked=True, color = ['b','g','r'], edgecolor='black', width=1, alpha=0.77, figsize=(16,8))
plt.title('PORCENTAJES DE CAUDAL EN TRAMO I')
plt.ylabel("Caudal (%)")
plt.xlabel('Fecha')
plt.legend(loc='best')
plt.savefig("BLOQUE I.png", bbox_inches="tight", dpi=160)
Result:
I want the same graphic but since 2009, and with the x-axis label each six moths.
I would like to get something like this (I’ve done it with photoshop):
You can concatenate your dataframe with another one containing the rest of the dates you are interested in and then plot that.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# Create dummy data
dates = pd.date_range('2/2017', '8/2022', freq='M')
values = np.random.uniform(-100, 100, (len(dates), 3))
barras = pd.DataFrame(values, columns=['% PRINCIPAL', '% APORTES', '% ΔE'], index=dates)
# Create new dataframe with 0s for dates starting from 2009
add_dates = pd.date_range('1/2009', barras.index[0], freq='M')[:-1]
df_0 = pd.DataFrame(0, columns=['% PRINCIPAL', '% APORTES', '% ΔE'], index=add_dates)
# Concatenate everything into a single dataframe
barras = pd.concat([df_0, barras])
# Plot
fig, ax = plt.subplots(1,1, figsize=(16,8))
barras.set_index(barras.index.strftime('%Y-%m')).plot(
kind="bar",
stacked=True,
color = ['b','g','r'],
edgecolor='black',
width=1,
alpha=0.77,
ax=ax
)
new_ticks = ax.get_xticks()[barras.index.month.isin([1,1+6])]
ax.set_xticks(new_ticks)
plt.title('PORCENTAJES DE CAUDAL EN TRAMO I')
plt.ylabel("Caudal (%)")
plt.xlabel('Fecha')
plt.legend(loc='best')
plt.savefig("BLOQUE I.png", bbox_inches="tight", dpi=160)
EDIT: Now the code shows all the data and the temporal line is right.