Python – Two different bar charts next to each other
Question:
I am using matplotlib to analyze my data. For this I created a dataframe with following structure:
merge.set_index('index', inplace=True)
print(merge)
username mentioned_user
index
matthiashauer 73 10
derya_tn 67 5
renatekuenast 36 9
ralf_stegner 35 73
mgrossebroemer 33 12
... ... ...
katrinhelling 1 1
gydej 1 2
martingassner 1 2
daniludwigmdb 1 3
philipphartewig 1 1
Now I want to plot two bar charts in one row. One the left side, there should be the bar chart with "username" column (ascending, first 10 biggest values) and on the right side there should be the the bar chart with the "mentioned_user" column (ascending, first 10 biggest values). As the values of the columns are different, the y-axis label for each bar chart has to be different.
Here is the plot that I have so far:
merges = merge[:30]
font_color = '#525252'
hfont = {'fontname':'Calibri'}
facecolor = '#eaeaf2'
color_red = '#fd625e'
color_blue = '#01b8aa'
index = merges.index
column0 = merges['username']
column1 = merges['mentioned_user']
title0 = 'Spreading Hate'
title1 = 'Receiving Hate'
fig, axes = plt.subplots(figsize=(10,5), facecolor=facecolor, ncols=2, sharey=True)
fig.tight_layout()
axes[0].barh(index, column0, align='center', color=color_red, zorder=10)
axes[0].set_title(title0, fontsize=18, pad=15, color=color_red, **hfont)
axes[1].barh(index, column1, align='center', color=color_blue, zorder=10)
axes[1].set_title(title1, fontsize=18, pad=15, color=color_blue, **hfont)
# To show data from highest to lowest
plt.gca().invert_yaxis()
axes[0].set(yticks=merges.index, yticklabels=merges.index)
axes[0].yaxis.tick_left()
axes[1].yaxis.tick_right()
axes[0].tick_params(axis='y', colors='black') # tick color
for label in (axes[0].get_xticklabels() + axes[0].get_yticklabels()):
label.set(fontsize=13, color=font_color, **hfont)
for label in (axes[1].get_xticklabels() + axes[1].get_yticklabels()):
label.set(fontsize=13, color=font_color, **hfont)
plt.subplots_adjust(wspace=0, top=0.85, bottom=0.1, left=0.18, right=0.95)
filename = 'politicians_spread_vs_receive_hate'
plt.savefig(filename+'.png', facecolor=facecolor)
For the left plot, I get the correct order and y-axis labels. However for the right plot, I would need to order the data as well and would also need another y-axis label on the right side.
How can I do this?
Thanks in advance!
Answers:
However for the right plot, I would need to order the data as well …
Then you should re-order the merges
dataframe by mentioned_user
before drawing the bar on the second axis.
… and would also need another y-axis label on the right side.
For that, you’ll need to remove sharey=True
from the plt.subplots()
call and move the ticks of the second axis to the right with ax.yaxis.tick_right()
Here is a minimal example with fake data
fig, (ax1, ax2) = plt.subplots(figsize=(10, 5), ncols=2)
merges = merges.sort_values("username")
ax1.barh(merges.index, merges["username"], align='center')
ax1.set_title("Spreading Hate")
merges = merges.sort_values("mentioned_user")
ax2.barh(merges.index, merges["mentioned_user"], align='center')
ax2.set_title("Receiving Hate")
ax2.yaxis.tick_right()
plt.subplots_adjust(wspace=0, top=0.85, bottom=0.1, left=0.18, right=0.95)
I am using matplotlib to analyze my data. For this I created a dataframe with following structure:
merge.set_index('index', inplace=True)
print(merge)
username mentioned_user
index
matthiashauer 73 10
derya_tn 67 5
renatekuenast 36 9
ralf_stegner 35 73
mgrossebroemer 33 12
... ... ...
katrinhelling 1 1
gydej 1 2
martingassner 1 2
daniludwigmdb 1 3
philipphartewig 1 1
Now I want to plot two bar charts in one row. One the left side, there should be the bar chart with "username" column (ascending, first 10 biggest values) and on the right side there should be the the bar chart with the "mentioned_user" column (ascending, first 10 biggest values). As the values of the columns are different, the y-axis label for each bar chart has to be different.
Here is the plot that I have so far:
merges = merge[:30]
font_color = '#525252'
hfont = {'fontname':'Calibri'}
facecolor = '#eaeaf2'
color_red = '#fd625e'
color_blue = '#01b8aa'
index = merges.index
column0 = merges['username']
column1 = merges['mentioned_user']
title0 = 'Spreading Hate'
title1 = 'Receiving Hate'
fig, axes = plt.subplots(figsize=(10,5), facecolor=facecolor, ncols=2, sharey=True)
fig.tight_layout()
axes[0].barh(index, column0, align='center', color=color_red, zorder=10)
axes[0].set_title(title0, fontsize=18, pad=15, color=color_red, **hfont)
axes[1].barh(index, column1, align='center', color=color_blue, zorder=10)
axes[1].set_title(title1, fontsize=18, pad=15, color=color_blue, **hfont)
# To show data from highest to lowest
plt.gca().invert_yaxis()
axes[0].set(yticks=merges.index, yticklabels=merges.index)
axes[0].yaxis.tick_left()
axes[1].yaxis.tick_right()
axes[0].tick_params(axis='y', colors='black') # tick color
for label in (axes[0].get_xticklabels() + axes[0].get_yticklabels()):
label.set(fontsize=13, color=font_color, **hfont)
for label in (axes[1].get_xticklabels() + axes[1].get_yticklabels()):
label.set(fontsize=13, color=font_color, **hfont)
plt.subplots_adjust(wspace=0, top=0.85, bottom=0.1, left=0.18, right=0.95)
filename = 'politicians_spread_vs_receive_hate'
plt.savefig(filename+'.png', facecolor=facecolor)
For the left plot, I get the correct order and y-axis labels. However for the right plot, I would need to order the data as well and would also need another y-axis label on the right side.
How can I do this?
Thanks in advance!
However for the right plot, I would need to order the data as well …
Then you should re-order the merges
dataframe by mentioned_user
before drawing the bar on the second axis.
… and would also need another y-axis label on the right side.
For that, you’ll need to remove sharey=True
from the plt.subplots()
call and move the ticks of the second axis to the right with ax.yaxis.tick_right()
Here is a minimal example with fake data
fig, (ax1, ax2) = plt.subplots(figsize=(10, 5), ncols=2)
merges = merges.sort_values("username")
ax1.barh(merges.index, merges["username"], align='center')
ax1.set_title("Spreading Hate")
merges = merges.sort_values("mentioned_user")
ax2.barh(merges.index, merges["mentioned_user"], align='center')
ax2.set_title("Receiving Hate")
ax2.yaxis.tick_right()
plt.subplots_adjust(wspace=0, top=0.85, bottom=0.1, left=0.18, right=0.95)