Search code examples
pythonmatplotlibwidth

control the width of barh graph


age_group = ['0~4 years', '5~9 years', '10~14 years', '15~19 years', '20~24 years', '25~29 years', '30~34 years', '35~39 years', '40~44 years', '45~49 years', '50~54 years', '55~59 years', '60~64 years', '65~69 years', '70~74 years', '75~79 years', '80~84 years', '85~89 years', '90~94 years', '95~99 years', '100 and over']
male = [805852, 1133426, 1186319, 1198911, 1681183, 1954718, 1759768, 1877724, 2038116, 2100431, 2243979, 2064943, 2016321, 1433783, 975415, 685723, 447622, 189457, 47148, 8149, 1056]
female = [764557, 1078946, 1118371, 1114388, 1542471, 1708409, 1572504, 1744623, 1943594, 2033792, 2233654, 2032973, 2081537, 1542824, 1114229, 898881, 731214, 428224, 161610, 35719, 5507]


# your code here
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

plt.figure(figsize = (20, 12))
female_array = np.array(female)
plt.barh(age_group, male, label = "Male", color = "turquoise")
plt.barh(age_group, -female_array, label = "Female", color = "violet")
plt.xticks([])
plt.tick_params(axis = "y", color = "w")
plt.title("Population of Korea in 2021", fontsize = 25)

for index, value in enumerate(male):
    plt.text(value + 25000, index, format(round(value, -3), ",d"))
    
for index, value in enumerate(female_array):
    plt.text(-value - 250000, index, format(round(value, -3), ",d"))
    
plt.box(False)
plt.legend(fontsize = 13)

I wrote down the code above to replicate the same graph which I attached. However, because of the Female index and the text of y axis are too close, I would like to control the whole barh graph narrower. Could you give me some code to make my python graph more similar to the picture?

enter image description here


Solution

  • So you can easily add padding for your ylabels padding by using tick_param. adding padding on the right is a little tricky, I'm doing this in a hacky way by adding a blank plot on the right. You can customize the padding on either side to make it appear as you prefer:

    # change the width ratio here if you want more padding on the right
    fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, figsize = (20, 10), gridspec_kw={'width_ratios': [30, 1]})
    
    ax2.axis('off') # hide 2nd axis
    female_array = np.array(female)
    bar1 = ax1.barh(age_group, np.array(male), label = "Male", color = "turquoise")
    bar2 = ax1.barh(age_group, -female_array, label = "Female", color = "violet")
    
    ax1.spines['top'].set_visible(False)
    ax1.spines['right'].set_visible(False)
    ax1.spines['bottom'].set_visible(False)
    ax1.spines['left'].set_visible(False)
    
    ax1.tick_params(axis = "y", color = "w")
    ax1.tick_params(axis='y', which='major', pad=55) # change the padding here
    ax1.set_title("Population of Korea in 2021", fontsize = 25)
    
    ax1.bar_label(bar1, labels=[f'{val:,}' for val in np.round(male, -3)])
    ax1.bar_label(bar2, labels=[f'{val:,}' for val in np.round(female_array, -3)])
    ax1.set_xticks([])
    ax1.legend(fontsize = 13)
    plt.show()
    

    Image:

    New Image

    compare to your original image:

    Original Code's Image