问题描述
我正在尝试为随机过程制作一个简单的动画(只是黑白点随机改变它们的颜色)。为了模拟这一点,我基本上在网格上绘制了点。然而,对我来说重要的参数是黑点的比率,我想在这个网格下绘制一个渐进条,显示比率 #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.colorbar 的 spacing="proportional"
参数确保黑/白区域与 bin 成正比。
Matplotlib Tutorials 值得投入时间。