0

I have two different dataframes:

df_test1 = pd.DataFrame(
    [['<18', 80841], ['18-24', 334725], ['25-44', 698261], ['45-64', 273087], ['65+', 15035]],
    columns = ['age_group', 'total_arrests']
)

enter image description here

df_test2 = pd.DataFrame(
    [['<18', 33979], ['18-24', 106857], ['25-44', 219324], ['45-64', 80647], ['65+', 4211]],
    columns = ['age_group','total_arrests']
)

enter image description here

I created the following plot using matplotlib:

fig, ax = plt.subplots()

ax.bar(df_test1.age_group, df_test1.total_arrests, color = 'seagreen')
ax.bar(df_test2.age_group, df_test2.total_arrests, color = 'lightgreen')
ax.set_xlabel('Age Group')
ax.set_ylabel('Number of Arrests')
ax.set_title('Arrests vs. Felony Arrests by Age Group')
plt.xticks(rotation=0)
plt.legend(['All Arressts', 'Felony Arrests'])

ax.yaxis.set_major_formatter(
ticker.FuncFormatter(lambda y,p: format(int(y), ','))
)

for i,j in zip(df_test1.age_group, df_test1.total_arrests):
    ax.annotate(format(j, ','), xy=(i,j))

for i,j in zip(df_test2.age_group, df_test2.total_arrests):
    ax.annotate(format(j, ','), xy=(i,j))

plt.show()

enter image description here

I was expecting 2 separate bars, one for each dataframe column, df_test1.total_arrests and df_test2.total_arrests but instead I got a stacked bar chart. How can I get a chart with bars next to one another similar to the chart here Matplotlib plot multiple bars in one graph ? I tried adjusting my code to the one in that example but I couldn't get it.

1 Answer 1

1

With only two bars, it's fairly easy. The solution is to align the bars on the "edge" of the tick, one bar is aligned to the left, the other to the right.

Repeat the same logic for proper alignment of the annotations. Half of them are left-aligned, the others are right-aligned

fig, ax = plt.subplots()

ax.bar(df_test1.age_group, df_test1.total_arrests, color = 'seagreen', width=0.4, align='edge')
ax.bar(df_test2.age_group, df_test2.total_arrests, color = 'lightgreen', width=-0.4, align='edge')
ax.set_xlabel('Age Group')
ax.set_ylabel('Number of Arrests')
ax.set_title('Arrests vs. Felony Arrests by Age Group')
plt.xticks(rotation=0)
plt.legend(['All Arressts', 'Felony Arrests'])
ax.yaxis.set_major_formatter(
matplotlib.ticker.FuncFormatter(lambda y,p: format(int(y), ','))
)

for i,j in zip(df_test1.age_group, df_test1.total_arrests):
    ax.annotate(format(j, ','), xy=(i,j))

for i,j in zip(df_test2.age_group, df_test2.total_arrests):
    ax.annotate(format(j, ','), xy=(i,j), ha='right')

plt.show()

enter image description here

If you have more than 2 bars, then the situation is more complicated (see the code that you linked above). You'll have an easier time using seaborn, but you have to transform your dataframe a bit:

df = pd.merge(left=df_test1, right=df_test2, on='age_group')

df.columns=['age_group','all_arrests', 'felonies']
df = df.melt(id_vars=['age_group'], var_name='Type', value_name='Number')

fig, ax = plt.subplots()
sns.barplot(y='Number',x='age_group',hue='Type', data=df, hue_order=['felonies','all_arrests'])

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.