使用 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',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),y=25)
            for line in range(n):
               colors = [color(config[line][raw]) for raw in raws]
               plt.scatter([line]*n,s=50)

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

            samp = Slider(axamp,color='black')

plt.show()

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

解决方法

我不认为 Slider 是用来做这样的动画的……如果有更好的方法,请告诉我……

也许使用自定义颜色条会起作用。我改编自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 决定颜色的分布方式。该示例使用两种颜色,黑色/白色,并使用 bin 边缘的黑点百分比定义了介于 0 和 100 之间的两个 bin。

Figure.colorbarspacing="proportional" 参数确保黑/白区域与 bin 成正比。


Example plot


Matplotlib Tutorials 值得投入时间。