I create the next function to plotting barplotd and I want to use this function to make subplots, but when I try it I don't get the result I expect:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
def plotsApilate(data,posColInit,posColEnd, tittleComplement, ax=None):
data['total']=data.iloc[:,posColInit:posColEnd].sum(axis=1)
data= data.sort_values(by='total', ascending=True).drop('total', axis=1)
if ax is None:
# Gráfico de barras apiladas horizontales
fig, ax = plt.subplots(figsize=(8,9))
data.set_index('variable')[['negative', 'neutral', 'positiv']].plot(kind='barh', stacked=True, ax=ax )
# Show tikcs
for container in ax.containers:
ax.bar_label(container, label_type='center',fontsize=6)
plt.title('Kind of Category' + ' ' + tittleComplement)
plt.xlabel('Quantity')
plt.ylabel('Variables')
plt.legend(title='Legend:')
plt.show()
# EXAMPLE
Categories= ['CAT1', 'CAT2', 'CAT3', 'CAT4', 'CAT5', 'CAT6']
negative1 = np.random.randint(0, 100, 6)
neutral1= np.random.randint(0, 100, 6)
positiv1= np.random.randint(0, 100, 6)
negative2 = np.random.randint(42, 100, 6)
neutral2= np.random.randint(42, 100, 6)
positiv2= np.random.randint(42, 100, 6)
# CreaTE dataframes
data1 = {'variable': Categories, 'negative': negative1, 'positiv': positiv1, 'neutral': neutral1}
df1 = pd.DataFrame(data1)
data2 = {'variable': Categories, 'negative': negative2, 'positiv': positiv2, 'neutral': neutral2}
df2 = pd.DataFrame(data2 )
# Create figure and subplots
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 6))
# Ploting 1st DF
plotsApilate(df1, 2,4,'XXX', ax1)
# Ploting 2nd DF
plotsApilate(df2, 2,4,'YYY', ax2)
# fix design
plt.tight_layout()
plt.show()
I have the next resut, what is the error in the code? I want one graph for each df.
The call to plt.show
within the function interrupts your example when you have only plotted the first data set. So that is why you get the first figure with only the left-hand chart. The titles for the first data set are on the wrong subplot because you use plt.title
, etc, which uses the active axes. If you have not explicitly set an active axes with plt.sca
, this will be the most recently created axes.
When you try to plot the second data set, the axes you want is on a figure that has been closed down. The plt
functions therefore create a new figure, so all you get is the title, labels and an empty legend.
So my solution is
plt.show()
within the functionKeeping your example as-is and just changing the function:
def plotsApilate(data,posColInit,posColEnd, tittleComplement, ax=None):
data['total']=data.iloc[:,posColInit:posColEnd].sum(axis=1)
data= data.sort_values(by='total', ascending=True).drop('total', axis=1)
if ax is None:
# Gráfico de barras apiladas horizontales
fig, ax = plt.subplots(figsize=(8,9))
data.set_index('variable')[['negative', 'neutral', 'positiv']].plot(kind='barh', stacked=True, ax=ax )
# Show tikcs
for container in ax.containers:
ax.bar_label(container, label_type='center',fontsize=6)
ax.set_title('Kind of Category' + ' ' + tittleComplement)
ax.set_xlabel('Quantity')
ax.set_ylabel('Variables')
ax.legend(title='Legend:')