1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
| frames = [] steps = [] #设置颜色条刻度值,范围从1到最大数。确诊病例任何国家迄今 max_country_confirmed_cases = cases_by_date[dates_list[-1]]["confirmed_cases"].max()
#考虑到案例数量的显着差异,我们希望标度为对数 high_tick = np.log1p(max_country_confirmed_cases) low_tick = np.log1p(1) log_tick_values = np.geomspace(low_tick, high_tick, num=6)
#但是,我们希望尺度上的/ labels /是实际的案例数(即不是log(n_cases)) visual_tick_values = np.expm1(log_tick_values).astype(int) #由于舍入误差- #明确设置最大CBAR值,否则它可能是最大 visual_tick_values[-1] = max_country_confirmed_cases visual_tick_values = [f"{val:,}" for val in visual_tick_values]
#生成折线图数据 元组的列表#:[(confirmed_cases,死亡),...] cases_deaths_totals = [(df.filter(like="confirmed_cases").astype("uint32").agg("sum")[0], df.filter(like="deaths").astype("uint32").agg("sum")[0]) for df in cases_by_date.values()]
confirmed_cases_totals = [daily_total[0] for daily_total in cases_deaths_totals] deaths_totals =[daily_total[1] for daily_total in cases_deaths_totals]
#该循环为每个帧生成数据 for i, (date, data) in enumerate(cases_by_date.items(), start=1): df = data
#z比例尺(用于计算每个国家的颜色)需要为对数 df["confirmed_cases_log"] = np.log1p(df["confirmed_cases"])
df["text"] = ( date + "<br>" + df["country"] + "<br>Confirmed cases: " + df["confirmed_cases"].apply(lambda x: "{:,}".format(x)) + "<br>Deaths: " + df["deaths"].apply(lambda x: "{:,}".format(x)) )
#创建Choropleth图表 choro_trace = go.Choropleth( **{ "locations": df["alpha-3_code"], "z": df["confirmed_cases_log"], "zmax": high_tick, "zmin": low_tick, "colorscale": "reds", "colorbar": { "ticks": "outside", "ticktext": visual_tick_values, "tickmode": "array", "tickvals": log_tick_values, "title": {"text": "<b>Confirmed Cases</b>"}, "len": 0.8, "y": 1, "yanchor": "top" }, "hovertemplate": df["text"], "name": "", "showlegend": False } ) #创建已确认的案例trace confirmed_cases_trace = go.Scatter( x=dates_list, y=confirmed_cases_totals[:i], mode="markers" if i == 1 else "lines", name="Total Confirmed Cases", line={"color": "Red"}, hovertemplate="%{x}<br>Total confirmed cases: %{y:,}<extra></extra>" ) #创建死亡跟踪 deaths_trace = go.Scatter( x=dates_list, y=deaths_totals[:i], mode="markers" if i == 1 else "lines", name="Total Deaths", line={"color": "Black"}, hovertemplate="%{x}<br>Total deaths: %{y:,}<extra></extra>" )
if i == 1: #第一帧是个什么人物最初显示.. fig.add_trace(choro_trace, row=1, col=1) fig.add_traces([confirmed_cases_trace, deaths_trace], rows=[2, 2], cols=[1, 1]) #...和所有其他帧被附加到`frames`列表和滑块 frames.append({"data": [choro_trace, confirmed_cases_trace, deaths_trace], "name": date})
steps.append( {"args": [[date], frame_args(50)], "label": date, "method": "animate",} )
#整理轴和最终确定图表准备好用于显示 fig.update_xaxes(range=[0, len(dates_list)-1], visible=False) fig.update_yaxes(range=[0, max(confirmed_cases_totals)]) fig.frames = frames fig.layout.sliders[0].steps = steps fig.layout.geo.domain = {"x": [0,1], "y": [0.2, 1]} fig.update_layout( height=650, legend={"x": 0.05, "y": 0.175, "yanchor": "top", "bgcolor": "rgba(0, 0, 0, 0)"}) fig
|