Search code examples
pythonpandasmatplotliblist-comprehension

Wrapping Y-tick labels in Bold Removes whitespace


I have this code:

s = """level,cvc
Vasopressor dose,0
Low, 0.263
Med, .563
High, 0.777
Vasopressor trend,0
Decreasing, 0.367
Stable, 0.521
Increasing, 0.714
Duration,0
8 hours, 0.478
24 hours, 0.591
PIV Location,0
Upper Arm, 0.528
Forearm, 0.541
Case,0
7, 0.541
8, 0.526
9, 0.507
10, 0.564"""

data = np.array([a.split(',') for a in s.split("\n")])

#print(data)
cvc = pd.DataFrame(data[1:], columns=data[0])
cvc['cvc'] = cvc['cvc'].apply(float)

#print(cvc)
variableNames = {'Vasopressor dose', 'Vasopressor trend', 'Duration', 'PIV Location', 'Case'}

font_color = '#525252'
hfont = {'fontname':'DejaVu Sans'}
facecolor = '#eaeaf2'
index = cvc.index#['level']
column0 = cvc['cvc']*100
title0 = 'Central Line Placed'


fig, axes = plt.subplots(figsize=(8, 12), facecolor=facecolor)
axes.barh(index, column0, align='center', color='darkslategray', zorder=10)
axes.set_title(title0, fontsize=18, pad=15, color='black', **hfont)

grid_params = dict(
    zorder=0,
    axis='x'
)

# If you have positive numbers and want to invert the x-axis of the left plot
axes.invert_xaxis() 
# To show data from highest to lowest
plt.gca().invert_yaxis()

axes.set(xlim = [0,100])

axes.yaxis.tick_left()
axes.set_yticks(range(len(cvc)))

formattedyticklabels = [r'$\bf{'+f"{t}"+r'}$' 
                        if t in variableNames else t for t in cvc['level']]
#print(formattedyticklabels)
axes.set_yticklabels(formattedyticklabels)
axes.grid(**grid_params)
fig.supxlabel("adjusted proportion of respondents", x = 0.62, size = 15)
axes.tick_params(axis='both', labelsize=15)
axes.tick_params(left = False)
fig.patch.set_facecolor('white')
plt.savefig("cvc.jpg")
    
fig.tight_layout()

plt.show()

enter image description here

For the y-tick labels with spaces, referred to in the set variableNames, those spaces are removed when I add the bold formatting. Any ideas how to get around this? I have referred to this question but not sure how to implement it in my list comprehension:

formattedyticklabels = [r'$\bf{'+f"{t}"+r'}$' 
                        if t in variableNames else t for t in cvc['level']]

Any tips?


Solution

  • I would suggest using set_fontweight for the individual labels. E.g., instead of this:

    formattedyticklabels = [r'$\bf{'+f"{t}"+r'}$' 
                            if t in variableNames else t for t in cvc['level']]
    
    axes.set_yticklabels(formattedyticklabels)
    

    You can use:

    axes.set_yticklabels(cvc['level'])
    
    for label in axes.get_yticklabels():
        if label.get_text() in variableNames:
            label.set_fontweight('bold')
    

    Result:

    plot

    Alternatively, you can make your initial approach work by first splitting the string on the whitespaces, then applying the pattern to each individual word, and finally joining them again:

    formattedyticklabels = [" ".join([r'$\bf{' + word + '}$' for word in t.split(' ')])
                            if t in variableNames else t for t in cvc['level']]
    
    axes.set_yticklabels(formattedyticklabels)
    

    Should get you the same result as above.