使用 matplotlib 制作简单的动画

simple animation with matplotlib

我正在尝试为随机过程制作一个简单的动画(只是随机改变颜色的黑白点)。为了模拟这一点,我基本上在网格上绘制了点。然而,对我来说重要的参数是黑点的比率,我想在这个网格下绘制一个进度条,显示比率 #blackdots/#totaldots 看起来大约像这样:[////////// /////////////_____] 70%(就像充电条一样)。

我试过了,但是条被覆盖了,我不认为 Slider 是用来做这样的动画的。

import numpy as np
import matplotlib.pyplot as plt
import random
from matplotlib.widgets import Slider

t=1500
d=5
n=10
raws = [i for i in range(n)]

config = [[2*random.randrange(2)-1 for i in range(n)] for i in range(n)]

def color(op):
    if op == 1:
        return 'white'
    return 'black'

nbblack = 0
for i in config:
  for j in i :
     nbblack += (j==-1)

blackrate = nbblack/(n**2)

plt.subplots_adjust(bottom=0.25)

for line in range(n):
    colors = [color(config[line][raw]) for raw in raws]
    plt.scatter([line]*n,raws,c=colors,edgecolors='black',s=50)

plt.title('t=0',fontdict={'size': 16},x=-0.20,y=25)

samp = Slider(axamp, 'Rate', 0, 1, valinit=blackrate,color='black')

for step in range(t):

    plt.pause(0.001)

    xpick = random.randrange(n)
    ypick = random.randrange(n)
    opinion_picked = config[xpick][ypick]
    for j in range(d) :
        neighboor = random.randrange(n),random.randrange(n)
        opinion_neig = config[neighboor[0]][neighboor[1]]
        if opinion_neig == opinion_picked :
            break

        elif j == d-1 :
            config[xpick][ypick]=-config[xpick][ypick]
            nbblack-=config[xpick][ypick]
            blackrate = nbblack/(n**2)
            plt.title('t={}'.format(step),fontdict={'size': 16},x=-0.20,y=25)
            for line in range(n):
               colors = [color(config[line][raw]) for raw in raws]
               plt.scatter([line]*n,raws,c=colors,edgecolors='black',s=50)

            axamp = plt.axes([0.28, 0.15, 0.48, 0.03])

            samp = Slider(axamp, 'Rate', 0, 1, valinit=blackrate,color='black')

plt.show()

我对 maplot 不是很熟悉所以如果有更好的方法请告诉我,非常感谢您的帮助!

I don't think that Slider is meant to do such animations ... please let me know if there is a better way to do things ...

也许使用自定义颜色条会奏效。我改编自 Discrete Intervals colorbar example.

下面使用黑色点的百分比来决定颜色条的哪个部分应该是黑色或白色。

这是一个没有动画的例子:循环绘制的五个连续图。我试着让它尽可能接近你的例子。

import matplotlib as mpl
from matplotlib import pyplot as plt
import random

t = 1500
d = 5
n = 10
raws = [i for i in range(n)]


def f(t=t, d=d, n=n, raws=raws):

    # try to get more skew in the data
    mode = random.random()
    config = [[random.triangular(mode=mode) > 0.5 for i in range(n)] for i in range(n)]
    config = [[int(item) or -1 for item in row] for row in config]
    # config = [[2*random.randrange(2)-1 for i in range(n)] for i in range(n)]

    def color(op):
        if op == 1:
            return "white"
        return "black"

    nbblack = 0
    for i in config:
        for j in i:
            nbblack += j == -1

    blackrate = nbblack / (n ** 2)

    fig, ax = plt.subplots()
    fig.subplots_adjust(bottom=0.25)
    # plt.subplots_adjust(bottom=0.25)

    for line in range(n):
        colors = [color(config[line][raw]) for raw in raws]
        plt.scatter([line] * n, raws, c=colors, edgecolors="black", s=50)

    plt.title("t=0", fontdict={"size": 16}, x=-0.20, y=25)

    cmap = mpl.colors.ListedColormap(["black", "white"])
    bounds = [0, int(blackrate * 100), 100]
    norm = mpl.colors.BoundaryNorm(bounds, cmap.N)
    fig.colorbar(
        mpl.cm.ScalarMappable(cmap=cmap, norm=norm),
        # cax=ax,
        # boundaries=[0] + bounds + [13],  # Adding values for extensions.
        # extend='both',
        ticks=bounds,
        spacing="proportional",
        orientation="horizontal",
        label="Percentage Black",
    )

    plt.show()
    plt.close()


for _ in range(5):
    f()

BoundaryNorm 确定颜色的分布方式。该示例使用两种颜色 black/white,并使用 bin 边缘 .

的黑点百分比定义了 0 到 100 之间的两个 bin

Figure.colorbarspacing="proportional" 参数确保 black/white 面积与 bin 成正比。



Matplotlib Tutorials 值得投入时间。