Issue
I can’t figure out how to make the graph transparent. I have a waveform graph from audio and fill the space with a background, I’m trying, but the background still appears on the graph.
def generate_waveform_image(save_dir, audio_file, output_filename, color='white', alpha=0, figsize=(12, 2), dpi=75):
fig, ax = plt.subplots(figsize=figsize, dpi=dpi, frameon=False)
plt.subplots_adjust(left=0, right=1, bottom=0, top=1)
samples, sr = librosa.load(audio_file, sr=None, mono=True)
times = np.arange(len(samples)) / sr
ax.plot(times, samples, color=color, alpha=alpha, linewidth=0.1)
ax.margins(0, 0)
ax.axis('off')
plt.savefig(os.path.join(save_dir, f'{output_filename}.png'), transparent=True, bbox_inches='tight',
pad_inches=0)
I tried everything and still_between, the background fills the entire image, but I need it to be like this:
ax.fill_between(times, -1, 1, color='gray', alpha=1)
Solution
plt.savefig(..., transparent=True)
makes the background transparent. But you seem to want to have the foreground transparent.
Here is an approach:
- optionally sets the
'agg'
backend, so nothing is shown on-screen - plots the wavefront, and sets margins to zero
- makes the figure's background transparent
fig.canvas.draw()
is needed to fill in the pixels- the pixels are copied to a numpy array
- the alpha values are inverted (the transparent background becomes opaque, the opaque curve becomes transparent, and the semi-transparent border of the curve gets its transparency inverted)
- all pixels are colored black while keeping the new transparency (the default color seems to be white, while the curve borders have the curve color, with semi-transparency)
- the numpy array is saved to file via PIL (Python's standard image library)
import matplotlib; matplotlib.use('agg')
import matplotlib.pyplot as plt
from PIL import Image
import numpy as np
fig, ax = plt.subplots(figsize=(12, 2))
values = np.random.randn(5000) * np.random.randn(5000).cumsum()
ax.plot(values, color='black', lw=1)
ax.margins(x=0) # no margins left and right
ax.axis('off') # hide the axes
fig.patch.set_alpha(0) # transparent
plt.subplots_adjust(bottom=0, left=0, top=1, right=1) # remove padding around the main plot
fig.canvas.draw() # "draw" is needed to fill in the pixels
buffer, (width, height) = fig.canvas.print_to_buffer()
data = np.array(np.frombuffer(buffer, np.uint8).reshape((height, width, 4)))
data[:, :, 3] = 255 - data[:, :, 3] # invert the transparency of all pixels
data[:, :, :3] = 0 # make all pixels black while keeping the new transparency
img = Image.fromarray(data)
img.save("transparent_waveform.png")
This is how the image looks inside Gimp:
Answered By - JohanC
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.