![](/img/trans.png)
[英]How can I annotate text/mark in matplotlib based on an if condition?
[英]How can I annotate a cell grid in matplotlib?
首先,如果我的问题看起来很简单,我很抱歉,但我是 python 初学者。 我已经写了一段时间了,这段代码使用元胞自动机对流行病的传播进行建模。 代码如下:
import matplotlib.colors
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import colors
from matplotlib.animation import FuncAnimation
import matplotlib.animation as ani
import random as rd
import random
import copy
from matplotlib.colors import ListedColormap
cmap=ListedColormap(['k','w','r','b'])
dead=0
untouched=1
ill=2
recovered=3
previous_state_matrix = []
current_state_matrix = []
n=50 #number of array (table of 50*50 : 2500 cells)
def init_graph():
plt.hlines(y=np.arange(0, 50)+0.5, xmin=np.full(50, 0)-0.5,linewidth=0.25,xmax=np.full(50, 50)-0.5, color="grey")
plt.vlines(x=np.arange(0, 50)+0.5, ymin=np.full(50, 0)-0.5,linewidth=0.25, ymax=np.full(50, 50)-0.5, color="grey")
def init_matrix_array():
global previous_state_matrix
global current_state_matrix
global n
for i in range (n):
previous_state_matrix.append([])
current_state_matrix.append([])
for j in range (n):
previous_state_matrix[i].append(1)
current_state_matrix[i].append(1)
previous_state_matrix[n//2][n//2]=2
current_state_matrix[n//2][n//2]=2
def next_to_ill_cell(i,j):
for x in [i-1,i,i+1]:
for y in [j-1,j,j+1]:
if not((x==i and y==j) or x==-1 or y==-1 or x==n or y==n):
if previous_state_matrix[x][y]==ill:
return True
#Rules
def process_next_state ():
global previous_state_matrix
global current_state_matrix
previous_state_matrix = copy.deepcopy(current_state_matrix)
for i in range (n) :
for j in range (n) :
if previous_state_matrix[i][j]==untouched
if next_to_ill_cell(i,j)== True:
k=rd.random()#random
if k >=0.5:
current_state_matrix[i][j]=ill
else:
current_state_matrix[i][j]=untouched
if previous_state_matrix[i][j]==ill:
s=rd.random()
if s>= 0.02875:
current_state_matrix[i][j]=recovered
else:
current_state_matrix[i][j]=dead
init_graph()
init_matrix_array()
print(current_state_matrix)
for k in range (len(current_state_matrix)):
for l in range (len(current_state_matrix[1])):
if current_state_matrix[k][l]==2:
plt.imshow(current_state_matrix, cmap=cmap, vmin=0, vmax=3)
process_next_state()
plt.pause(1)
plt.imshow(current_state_matrix, cmap=cmap, vmin=0, vmax=3)
plt.show()
我确信这段代码可以大大改进,但正如我所说,我是一个初学者。 现在我要做的是在 plot 的底部添加一个注释,以指示死亡次数和恢复次数。 我还想在 plot 的顶部指出经过的天数,这对应于从一个数字表到下一个数字表的转换。
请你帮助我好吗?
要标注死亡人数、康复人数和天数,至少需要计算这三个变量。 你需要这样的东西:
day = 1
while day < 1000:
n_death = ...
n_recovery = ...
...
plt.imshow(...)
plt.text(x, y, f'day = {day}')
plt.text(x, y, f'n_death = {n_death }')
plt.text(x, y, f'n_recovery = {n_recovery}')
我重组了你的代码,因为它很难阅读。 在 function 中更改全局变量是非常危险的。 你应该避免这种情况。
import matplotlib.colors
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import colors
from matplotlib.animation import FuncAnimation
import matplotlib.animation as ani
import random as rd
#import random
import copy
from matplotlib.colors import ListedColormap
def init_graph():
plt.hlines(y=np.arange(n)+0.5, xmin=-0.5, xmax=n-0.5, linewidth=0.25, color="grey")
plt.vlines(x=np.arange(n)+0.5, ymin=-0.5, ymax=n-0.5, linewidth=0.25, color="grey")
def init_matrix_array(n):
m = np.ones((n, n))
m[n//2][n//2]=2
return m.tolist()
def next_to_ill_cell(current_state_matrix, i, j):
for x in [i-1,i,i+1]:
for y in [j-1,j,j+1]:
if not((x==i and y==j) or x==-1 or y==-1 or x==n or y==n):
if current_state_matrix[x][y]==ill:
return True
return False
#Rules
def process_next_state (current_state_matrix):
previous_state_matrix = copy.deepcopy(current_state_matrix)
for i in range (n) :
for j in range (n) :
if previous_state_matrix[i][j] == untouched:
if next_to_ill_cell(previous_state_matrix, i, j)== True:
k = rd.random()#random
if k >= 0.5:
current_state_matrix[i][j] = ill
else:
current_state_matrix[i][j] = untouched
if previous_state_matrix[i][j]==ill: # elif???????
s = rd.random()
if s >= 0.02875:
current_state_matrix[i][j] = recovered
else:
current_state_matrix[i][j] = dead
return current_state_matrix
def number_of_death(current_state_matrix):
n_death = 0
for i in range(n):
for j in range(n):
if current_state_matrix[i][j] == dead:
n_death += 1
return n_death
def number_of_recovery(previous_state_matrix, current_state_matrix):
"""Calculate the number of recovery"""
# for k in range (len(current_state_matrix)):
# for l in range (len(current_state_matrix[1])):
# if current_state_matrix[k][l]==2:
# plt.imshow(current_state_matrix, cmap=cmap, vmin=0, vmax=3)
# process_next_state()
# plt.pause(1)
# plt.imshow(current_state_matrix, cmap=cmap, vmin=0, vmax=3)
if __name__ == '__main__':
cmap = ListedColormap(['k','w','r','b'])
dead = 0
untouched = 1
ill = 2
recovered = 3
n = 50 #number of array (table of 50*50 : 2500 cells)
init_graph()
current_state_matrix = init_matrix_array(n)
day = 1
while day < 10:
previous_state_matrix = current_state_matrix
# Number of death
n_death = number_of_death(current_state_matrix)
plt.imshow(current_state_matrix, cmap=cmap, vmin=0, vmax=3)
plt.text(25, 5, f'day = {day}', horizontalalignment='center')
plt.text(25, 45, f'number of death = {n_death}', horizontalalignment='center')
current_state_matrix = process_next_state(current_state_matrix)
day += 1
plt.pause(1)
plt.show()
我的意思是数字在 state 之后与 state 重叠,第二个出现在第一个等之上。我希望我让自己清楚。我得到以下 Z78E6221F6393D1356681DB39DZ:不可读的数字。 所以我希望新的数字取代旧的数字,而不仅仅是出现在它们上面,但我不知道该怎么做。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.