Search code examples
pythonmatplotlibplottextalpha

Matplotlib annotate/text: How can I set alpha transparency for facecolor and edgecolor separately?


I'm using the matplotlib plt.text function to add a textbox to my histogram. In the bbox argument I specify the boxstyle, facecolor, edgecolor, and alpha. However when I run this and display the plot, both the face of the box and its edge become transparent with respect to alpha. This slightly changes the both colors and I would like to just keep my edge solid. Does anyone know a way to set alpha such that the border stays opaque (alpha=1) but the facecolor can be set at any value (alpha = [0,1]).

Thank you.

import matplotlib.pyplot as plt
import statistics

fig, ax = plt.subplots()
ax.hist(x=data, bins='auto', color='#0504aa', alpha=0.7, rwidth=0.85)
plt.grid(axis='y', alpha=0.75)

textstr = '\n'.join((
    r'$n=%.2f$' % (len(data), ),
    r'$\mu=%.2f$' % (round(statistics.mean(data), 4), ),
    r'$\mathrm{median}=%.2f$' % (round(statistics.median(data), 4), ),
    r'$\sigma=%.2f$' % (round(statistics.pstdev(data), 4), )))

ax.text(0.05, 0.95, textstr, transform=ax.transAxes, fontsize=14,
        verticalalignment='top', bbox=dict(boxstyle='square,pad=.6',facecolor='lightgrey', edgecolor='black', alpha=0.7))

plt.show()

Solution

  • You can first compute the RGBA sequence of both of your colors, then alter the alpha parameter only for the facecolor and then pass the modified RGBA tuples to the text function

    from matplotlib import colors
    
    # Rest of your code
    
    fc = colors.to_rgba('lightgrey')
    ec = colors.to_rgba('black')
    
    fc = fc[:-1] + (0.7,) # <--- Change the alpha value of facecolor to be 0.7
    
    ax.text(0.05, 0.95, textstr, transform=ax.transAxes, fontsize=14,
            verticalalignment='top', bbox=dict(boxstyle='square,pad=.6',
            facecolor=fc, edgecolor=ec)) # <--- Assign the face and edgecolors