Search code examples
pythonmatplotlibtransparency

make matplotlib png plot semi-transparent with non integer alpha value


I know that I can produce a png plot with a transparent background in the following way (which works for me):

import matplotlib.pyplot as plt
plt.plot ([1,2,3],[2,1,3])
plt.savefig("test.png",transparent=True)

But how can I make the background semi-transparent, with an fractional alpha number? I read on a separate blog that one could do it like this:

fig,ax=plt.subplots()
ax.plot ([1,2,3],[2,1,3]) 
ax.patch.set_facecolor('white')
ax.patch.set_alpha(0.5)
plt.savefig('test.png', facecolor=fig.get_facecolor(), edgecolor='none')

But that didn't work for me and produces a plot without transparency and gave me this non transparent png (confirmed in ppt).

example output

In response to the comments,

plt.get_backend()

gives me 'MacOSX' and I am on

Python 3.9.4 (default, Apr 5 2021, 01:49:30) [Clang 12.0.0 (clang-1200.0.32.29)] on darwin


Solution

  • Your code behaved correctly and nothing is wrong. I tried it on colab and here is the results (notice the ax.patch.set_alpha() value):

    import matplotlib.pyplot as plt
    import numpy as np
    
    fig,ax=plt.subplots()
    ax.plot ([1,2,3],[2,1,3]) 
    ax.patch.set_facecolor('white')
    ax.patch.set_alpha(1)
    plt.savefig('test.png', facecolor=fig.get_facecolor(), edgecolor='none')
    

    enter image description here

    import matplotlib.pyplot as plt
    import numpy as np
    
    fig,ax=plt.subplots()
    ax.plot ([1,2,3],[2,1,3]) 
    ax.patch.set_facecolor('white')
    ax.patch.set_alpha(0)
    plt.savefig('test.png', facecolor=fig.get_facecolor(), edgecolor='none')
    

    enter image description here
    Updated: After saving the plot, you can load it with opencv then change its transparency like this:

    """
    pip install opencv-python
    """
    import cv2
    
    im = cv2.imread('test.png',cv2.IMREAD_UNCHANGED)
    im[:,:,3] = im[:,:,3]/2
    cv2.imwrite('adjust.png',im)
    

    Update 2: I think I found what you want:

    import matplotlib.pyplot as plt
    import numpy as np
    import cv2
    
    fig,ax=plt.subplots()
    ax.plot ([1,2,3],[2,1,3]) 
    ax.patch.set_facecolor('white')
    plt.savefig('original.png', edgecolor='none')
    plt.savefig('transparent.png', edgecolor='none',transparent=True)
    #Then
    im = cv2.imread('original.png',cv2.IMREAD_UNCHANGED)
    im[:,:,3] = im[:,:,3]/2 + 120
    cv2.imwrite('semi_transparent.png',im)
    

    Here is the results I got (tested on MS word):
    enter image description here