Я использую пакет gif
здесь , чтобы связать воедино сюжеты matplotlib в gifs. Тем не менее, я получаю артефакты на изображениях из-за того, что цвета ... Я не знаю формального слова, но "с пониженной выборкой".
Исходные графики выглядят так:
плавные согласованные изменения цвета в цветовых картах.
Однако, когда я использую пакет для конвертации в gif, я получаю это:
Надеюсь, вы сможете увидеть квантование / понижающую дискретизацию, которая происходит в цветах.
Код, который на самом деле выполняется, очень короткий (со строкой, которую я добавил, чтобы попробовать чтобы корректно работала цветовая коррекция, но она не работала - загруженный gif-файл с этой коррекцией, но выглядит так же, как и раньше)
def frame(func):
"""
Decorator for a matplotlib plot function.
Example:
```
@gif.frame
def plot(x, y):
plt.figure(figsize=(5, 5))
plt.scatter(x, y)
plt.xlim((0, 100))
plt.ylim((0, 100))
```
"""
@functools.wraps(func)
def wrapper(*args, **kwargs):
buffer = io.BytesIO()
func(*args, **kwargs)
plt.savefig(buffer, format="png")
buffer.seek(0)
image = Image.open(buffer)
### ADDED IN AFTER THE FACT ###
image = image.convert('RGBA', palette=Image.ADAPTIVE)
### ### ### ### ### ### ### ###
plt.close()
return image
return wrapper
def save(frames, path, duration=100):
"""
Save decorated frames to an animated gif.
- frames (list): collection of frames built with the frame decorator
- path (str): filename with relative or absolute path
- duration (int): milliseconds between frames
"""
frames[0].save(
path,
save_all=True,
append_images=frames[1:],
optimize=True,
duration=duration,
loop=0,
)
Любая идея, что я могу сделать с пакетом PIL, который будет поддерживать непрерывность цветовых карт при записи в GIF-файлы? Должен ли размер dpi / file-size быть очень большим, чтобы поддерживать это?
Вот код, который создал график, на всякий случай:
@gif.frame
def plot_signal_and_ft(t, t_step):
### Setup ###
dims = (501,501)
x = np.linspace(0,100,dims[0])
y = np.linspace(0,100,dims[1])
u = float(100/dims[0])
cen = [50.0, 50.0]
xx, yy = np.meshgrid(x, y, sparse=True)
signal = np.zeros(dims)
r = 25*(0.003125*np.exp(5.66643*(t/t_step))+0.046875)
offset = 1.0 + ((25.0-1.0)/(t_step))*t
pos1 = np.sqrt((xx-cen[0]+offset)*(xx-cen[0]+offset)+(yy-cen[1])*(yy-cen[1]))
pos2 = np.sqrt((xx-cen[0]-offset)*(xx-cen[0]-offset)+(yy-cen[1])*(yy-cen[1]))
sigma, mu = r, 0
signal += np.exp(-( (pos1-mu)**2 / ( 2.0 * sigma**2 ) ) )
signal += np.exp(-( (pos2-mu)**2 / ( 2.0 * sigma**2 ) ) )
# FT
F = np.fft.fftshift(np.fft.fft2(signal))
max_real = 10.0
max_imag = 3.0
### PLOTTING ###
f, ax = plt.subplots(figsize=(6, 6), nrows=2, ncols=2, dpi=100)
# SIGNAL
sig = ax[0,0].imshow(signal, cmap = plt.cm.Greys, vmin=0, vmax=1, origin="lower")
ax[0,0].axis("off")
ax[0,0].set_title("Signal", fontsize="medium", fontweight="bold",fontfamily="serif")
divider = make_axes_locatable(ax[0,0])
cax = divider.append_axes("right", size="5%", pad=0.1)
cbar = f.colorbar(sig, cax=cax)
cbar.set_ticklabels(["0.0", "0.2", "0.4", "0.6", "0.8", "1.0"])
# REAL
real = ax[1,0].imshow(np.real(F), cmap=mpl.cm.RdBu, clim=(-max_real, max_real),
norm=MidpointNormalize(midpoint=0.0, vmin=-max_real, vmax=max_real),
origin="lower")
ax[1,0].axis("off")
ax[1,0].set_title("R[FT]", fontsize="medium", fontweight="bold",fontfamily="serif")
divider = make_axes_locatable(ax[1,0])
cax = divider.append_axes("right", size="5%", pad=0.1)
f.colorbar(real, cax=cax)
# IMAG
imag = ax[1,1].imshow(np.imag(F), cmap=mpl.cm.PiYG, clim=(-max_imag, max_imag),
norm=MidpointNormalize(midpoint=0.0, vmin=-max_imag, vmax=max_imag),
origin="lower")
ax[1,1].axis("off")
ax[1,1].set_title("Im[FT]", fontsize="medium", fontweight="bold",fontfamily="serif")
divider = make_axes_locatable(ax[1,1])
cax = divider.append_axes("right", size="5%", pad=0.1)
f.colorbar(imag, cax=cax)
# MAGNITUDE
mag = ax[0,1].imshow(np.absolute(F), cmap=plt.cm.hot, clim=(0, max_real),
norm=MidpointNormalize(midpoint=max_real/2, vmin=0, vmax=max_real),
origin="lower")
ax[0,1].axis("off")
ax[0,1].set_title("||FT||", fontsize="medium", fontweight="bold",fontfamily="serif")
divider = make_axes_locatable(ax[0,1])
cax = divider.append_axes("right", size="5%", pad=0.1)
f.colorbar(mag, cax=cax)
plt.tight_layout()
t_steps = 10
frames = []
traj = [t for t in range(t_steps)] + [t_steps-t for t in range(t_steps)]
for t in traj:
frame = plot_signal_and_ft(t, t_steps)
frames.append(frame)
gif.save(frames, "./test_double.gif", duration=150)