为什么在动画 GIF 中没有使用完整的调色板?

huangapple go评论81阅读模式
英文:

Why isn't the full palette being used in an animated gif?

问题

I'm here to provide the translated content as requested. Here's the translated code portion:

我正在使用Pillow制作热图的动画gif由于有许多不同的值每一帧只能有256种颜色我希望Pillow可以为每一帧提供不同的调色板但似乎它没有使用大部分可用的颜色以下是一个最小化的示例

from PIL import Image
import seaborn as sns
import io
import matplotlib.pyplot as plt
import scipy
import math
import numpy as np
import imageio

vmin = 0
vmax = 0.4
images = []
for i in range(3):
    mu = 0
    variance = i + 0.1
    sigma = math.sqrt(variance)
    x = np.linspace(mu - 3 * sigma, mu + 3 * sigma, 400)
    row = scipy.stats.norm.pdf(x, mu, sigma)
    matrix = []
    for i in range(400):
        matrix.append(row)
    cmap = "viridis"
    hmap = sns.heatmap(matrix, vmin=vmin, vmax=vmax, cmap=cmap, cbar=False)
    hmap.set_xticks(range(0, 101, 4))
    buffer = io.BytesIO()
    plt.savefig(buffer, format='png')
    buffer.seek(0)
    images.append(Image.open(buffer))
    plt.clf()

images[0].save("out.gif", save_all=True, duration=1000, loop=1, append_images=images[1:])

Please note that the translated code above is the same as the original code, but in Chinese.

英文:

I am making an animated gif of heatmaps using pillow. As there are a lot of different values and each frame can only have 256 colors I was hoping pillow would give me a different palette per frame. But it seems it isn't using most of the available colors. Here is a MWE:

from PIL import Image
import seaborn as sns
import io
import matplotlib.pyplot as plt
import scipy
import math
import numpy as np
import imageio

vmin = 0
vmax = 0.4
images = []
for i in range(3):
    mu = 0
    variance = i+0.1
    sigma = math.sqrt(variance)
    x = np.linspace(mu - 3*sigma, mu + 3*sigma, 400)
    row = scipy.stats.norm.pdf(x, mu, sigma)
    matrix = []
    for i in range(400):
        matrix.append(row)
    cmap = "viridis"
    hmap = sns.heatmap(matrix, vmin=vmin, vmax=vmax, cmap=cmap, cbar=False)
    hmap.set_xticks(range(0, 101, 4))
    buffer = io.BytesIO()
    plt.savefig(buffer, format='png')
    buffer.seek(0)
    images.append(Image.open(buffer))
    plt.clf()

images[0].save("out.gif", save_all=True, duration=1000,  loop=1, append_images=images[1:])

The animated gif produced is:

为什么在动画 GIF 中没有使用完整的调色板?

You can see that later frames use fewer than 256 colors. If I look at the palettes with

identify -verbose  out.gif|grep Colors

I get these:

  • For the first frame: Colors: 46
  • For the second frame: Colors: 28
  • For the third frame: Colors: 19

If I save png's instead we can see the third frame, for example, has many more than 19 colors.

为什么在动画 GIF 中没有使用完整的调色板?

What am I doing wrong?

答案1

得分: 1

Matplotlib正在生成调色板图像,这导致PIL继续在相同的轨道上运行。通过使用以下方式给PIL更多的自由度:

images.append(Image.open(buffer).convert('RGB'))

你将会得到:

英文:

Matplotlib is making palette images and that is causing PIL to carry on down the same track. Give PIL more latitude by using:

images.append(Image.open(buffer).convert('RGB')

and you'll get:

为什么在动画 GIF 中没有使用完整的调色板?

huangapple
  • 本文由 发表于 2023年6月8日 15:26:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/76429520.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定