You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

流行病模拟散点图显示异常,如何修复为常规散点图?

流行病传播模拟可视化异常问题排查与解决

问题描述

编写了branch()函数模拟流行病传播,尝试用散点图可视化传播情况:x轴为代际(generation),y轴为该代感染人数。但绘制出的散点图显示异常,甚至无法响应配色方案修改,且迭代次数越多问题越严重。

原绘图代码

import numpy as np
import matplotlib.pyplot as plt
import scipy.stats
import networkx as nx

N=np.zeros(1000)
for x in range(99):
  infections = branch()
  list_length=len(infections)
  sumOfElements=0
  for i in range(list_length):
    infectionsum=sumOfElements+infections[i]
    N[x] = infectionsum
  #print(infections)
  genhouse = [0,1,2,3,4,5,6,7,8,9]
  #s = [3*s**2 for s in infections]
  plt.scatter(genhouse, infections)
  #plt.scatter(x, y, s=area, c=colors, alpha=0.5)
sum = np.sum(N)
print("the average epidemic size is", sum)
plt.title('Infections across Generations')
plt.xlabel('Generation')
plt.ylabel('Number of Infections')
plt.show()

原流行病模拟函数

def branch():
  r = .95 #reproduction number
  manygens = 10 #number of generations to simulate
  N=np.zeros(manygens+1) #how many children in each generation
  howmany = [2]
  G=nx.Graph() 
  count = 0 
  G.add_node(1, gen = count) #gen 0
  manynodes = 1 #how many nodes we currently have on the graph
  N[count] = 1 #one child in gen 0
  for g in range(manygens): #run through generations
    thisgen = 0 #counter for infections this generation
    for node, gen in nx.get_node_attributes(G, "gen").items():
      if gen == g: 
        y = scipy.stats.poisson.rvs(mu=r, size=1) #see how many are infected
        if y < 1: #if less than 1 person is infected (no more reproduction from)
         break
        else:
          reset = 0
          while y >= 1:
            G.add_node(manynodes + 1, gen = count + 1) #add the infected node
            G.add_edge(node, manynodes + 1) #connect to parent
            manynodes = manynodes + 1 #increase node counter
            y = y - 1 #each node we add take away 1 from y
            thisgen = thisgen + 1

          count = count + 1
    howmany.append(thisgen)      
  #nx.draw_spring(G) turn this on to show the graph
  howmany.pop(-1)
  #print(howmany)
  return howmany

问题原因

  • 绘图逻辑重复叠加:每次循环都调用plt.scatter绘制一整组10个代际的散点,99次循环后同一张图上叠加了99组数据,点过度重叠导致视觉混乱,配色修改被大量重叠的点覆盖,无法显现效果。
  • 模拟函数逻辑错误:
    • 当某节点的感染数y<1时使用break直接终止当前代的遍历,导致同代其他节点未被处理,统计的该代感染人数严重失真;
    • count变量在单个节点处理完成后就递增,而非每代处理完后递增,导致代际标记混乱,返回的howmany数组数据异常;
    • 初始howmany = [2]与gen0实际1个感染节点不符,初始数据错误。
  • 平均规模统计错误:N[x] = infectionsum每次只赋值最后一次累加结果,未正确统计每次模拟的总感染人数,导致最终平均计算结果错误。

解决方案

1. 修正branch()模拟函数

def branch():
    r = .95  # reproduction number
    manygens = 10  # number of generations to simulate
    G = nx.Graph() 
    count = 0 
    G.add_node(1, gen=count)  # gen 0 has 1 node
    manynodes = 1
    howmany = [1]  # gen0 initial infection count is 1

    for g in range(manygens):  # process each generation
        thisgen = 0
        # Get all nodes in current generation
        current_gen_nodes = [node for node, attr in G.nodes(data=True) if attr['gen'] == g]
        for node in current_gen_nodes:
            y = scipy.stats.poisson.rvs(mu=r, size=1)[0]  # get scalar value instead of array
            if y < 1:
                continue  # skip this node, don't break the whole generation
            while y >= 1:
                manynodes += 1
                G.add_node(manynodes, gen=count + 1)
                G.add_edge(node, manynodes)
                y -= 1
                thisgen += 1
        count += 1  # increment generation after processing all nodes in current gen
        howmany.append(thisgen)
    howmany.pop(-1)  # remove the extra entry from manygens loop
    return howmany

2. 调整绘图逻辑(两种可选方式)

方式一:绘制所有模拟的散点(添加透明度区分)

import numpy as np
import matplotlib.pyplot as plt
import scipy.stats
import networkx as nx

num_simulations = 99
genhouse = np.arange(10)  # 0-9 generations
all_infections = []
total_cases = 0

for _ in range(num_simulations):
    infections = branch()
    all_infections.append(infections)
    total_cases += sum(infections)
    # 绘制单次模拟的散点,设置低透明度避免重叠遮挡
    plt.scatter(genhouse, infections, alpha=0.2, color='blue')

# 计算每代平均感染人数并绘制
avg_infections = np.mean(all_infections, axis=0)
plt.scatter(genhouse, avg_infections, color='red', s=80, label='Average Infections')

plt.title('Infections across Generations')
plt.xlabel('Generation')
plt.ylabel('Number of Infections')
plt.legend()
plt.show()

print("The average epidemic size is", total_cases / num_simulations)

方式二:仅绘制每代平均感染人数的散点

import numpy as np
import matplotlib.pyplot as plt
import scipy.stats
import networkx as nx

num_simulations = 99
genhouse = np.arange(10)
all_infections = []
total_cases = 0

for _ in range(num_simulations):
    infections = branch()
    all_infections.append(infections)
    total_cases += sum(infections)

avg_infections = np.mean(all_infections, axis=0)
plt.scatter(genhouse, avg_infections, color='darkorange', s=60)

plt.title('Average Infections across Generations')
plt.xlabel('Generation')
plt.ylabel('Average Number of Infections')
plt.show()

print("The average epidemic size is", total_cases / num_simulations)

内容的提问来源于stack exchange,提问作者slacks37

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 13:45:46