【问题标题】:Plot death count against date with Matplotlib使用 Matplotlib 根据日期绘制死亡人数
【发布时间】:2020-08-26 06:24:26
【问题描述】:

我有这个 Python 程序来绘制一段时间内冠状病毒死亡人数的图表:

import datetime
import matplotlib.dates as mdates
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

from matplotlib.animation import FuncAnimation

plt.style.use('fivethirtyeight')

data = pd.read_csv('csv_data/NI_CORONA_DATA.csv')

x_vals = []
y_vals_tests_done = []
y_vals_positive_tests = []
y_vals_deaths = []


def animate(i):
    x = data['Date']
    y_deaths = data['Deaths']
    x_vals = np.array([datetime.datetime.strptime(d, '%d/%m/%Y').date() for d in x])
    y_vals_deaths = np.array(y_deaths[0:i])

    plt.cla()
    plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%d/%m/%Y'))
    plt.gca().xaxis.set_major_locator(mdates.DayLocator())
    plt.ylim(0, 500)

    plt.plot(x_vals, y_vals_deaths, label='Deaths')

    plt.legend(loc='upper left')

    plt.tight_layout()


ani = FuncAnimation(plt.gcf(), animate, frames=len(data.index) + 1, interval=100, repeat=False)

plt.show()

这是我的数据集:

Date,Tested,Positive,Deaths
03/02/2020,1,0,0
04/02/2020,1,0,0
05/02/2020,1,0,0
06/02/2020,2,0,0
07/02/2020,8,0,0
08/02/2020,12,0,0
09/02/2020,15,0,0
10/02/2020,19,0,0
11/02/2020,21,0,0
12/02/2020,21,0,0
13/02/2020,24,0,0
14/02/2020,27,0,0
15/02/2020,28,0,0
16/02/2020,28,0,0
17/02/2020,35,0,0
18/02/2020,38,0,0
19/02/2020,41,0,0
20/02/2020,42,0,0
21/02/2020,45,0,0
22/02/2020,45,0,0
23/02/2020,47,0,0
24/02/2020,49,0,0
25/02/2020,73,0,0
26/02/2020,115,1,0
27/02/2020,157,1,0
28/02/2020,184,1,0
29/02/2020,199,1,0
01/03/2020,209,1,0
02/03/2020,228,1,0
03/03/2020,255,2,0
04/03/2020,282,2,0
05/03/2020,309,5,0
06/03/2020,329,7,0
07/03/2020,350,12,0
08/03/2020,381,16,0
09/03/2020,443,19,0
10/03/2020,598,22,0
11/03/2020,759,32,0
12/03/2020,894,36,0
13/03/2020,1028,47,0
14/03/2020,1146,57,0
15/03/2020,1254,61,0
16/03/2020,1404,70,0
17/03/2020,1540,80,0
18/03/2020,1743,94,1
19/03/2020,1938,108,2
20/03/2020,2192,126,2
21/03/2020,2403,149,3
22/03/2020,2606,167,4
23/03/2020,2995,212,9
24/03/2020,3355,252,11
25/03/2020,3779,313,15
26/03/2020,4245,391,17
27/03/2020,4653,461,20
28/03/2020,5010,541,28
29/03/2020,5319,599,32
30/03/2020,5768,683,36
31/03/2020,6249,792,41
01/04/2020,6781,898,45
02/04/2020,7249,1007,55
03/04/2020,7626,1097,65
04/04/2020,7959,1174,74
05/04/2020,8224,1234,85
06/04/2020,8670,1335,91
07/04/2020,9171,1468,99
08/04/2020,9709,1568,103
09/04/2020,10320,1671,121
10/04/2020,10871,1770,132
11/04/2020,11214,1832,143
12/04/2020,11619,1911,159
13/04/2020,12026,2020,166
14/04/2020,12535,2124,178
15/04/2020,13184,2262,194
16/04/2020,13831,2406,205
17/04/2020,14532,2574,214
18/04/2020,14971,2661,224
19/04/2020,15270,2706,234
20/04/2020,15840,2821,246
21/04/2020,16570,2963,259
22/04/2020,17255,3084,278
23/04/2020,17808,3164,284
24/04/2020,18463,3252,303
25/04/2020,18921,3310,318
26/04/2020,19386,3356,332
27/04/2020,20228,3440,344
28/04/2020,21817,3511,350
29/04/2020,22240,3593,364
30/04/2020,23370,3684,372
01/05/2020,24641,3775,384
02/05/2020,25622,3834,396
03/05/2020,26241,3869,407
04/05/2020,27453,3922,415
05/05/2020,28708,3974,421
06/05/2020,30126,4013,424
07/05/2020,31435,4073,426
08/05/2020,32464,4114,430
09/05/2020,32634,4119,432
10/05/2020,32634,4119,435

我正在尝试在 x 轴上显示日期,在 y 轴上显示死亡人数。

当我运行我到目前为止所做的事情时,我在plt.plot(x_vals, y_vals_deaths, label='Deaths') 线上遇到了这个错误:

    raise ValueError(f"x and y must have same first dimension, but "
ValueError: x and y must have same first dimension, but have shapes (98,) and (0,)

最初我没有将x_valsy_vals_deaths 设置为np.array,但阅读这可能有助于解决我的问题。不幸的是,它没有任何区别。

我该如何解决这个问题?

【问题讨论】:

    标签: python python-3.x datetime matplotlib


    【解决方案1】:

    您的 xy 尺寸必须相同 - 您将死亡 (y) 缩短为 [0:i] 但保留所有日期时间 (x) - 因此尺寸不同。

    可能的修复:

    def animate(i):
    
        x = data['Date'][0:i]                    # shorten this one as well
        y_deaths = data['Deaths']
        x_vals = np.array([datetime.datetime.strptime(d, '%d/%m/%Y').date() for d in x]) 
        y_vals_deaths = np.array(y_deaths[0:i])  # same size as this one
    
        plt.cla()
        plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%d/%m/%Y')) 
        plt.gca().xaxis.set_major_locator(mdates.DayLocator())
        plt.ylim(0, 500)
    
        plt.plot(x_vals, y_vals_deaths, label='Deaths')
        plt.legend(loc='upper left')
        plt.tight_layout()
    

    如果您不希望这样做,您可能想研究如何将 y_vals_deaths 与充满 None 的 ndarray 连接到 x 的大小,如下所示:

    def animate(i):
        x = data['Date'] 
        nones = [None] * len(x)
    
        y_deaths = data['Deaths']
        x_vals = np.array([datetime.datetime.strptime(d, '%d/%m/%Y').date() for d in x]) 
        # enlarge to same size as x by concatting a None-Slice
        y_vals_deaths = np.concatenate([ np.array(y_deaths[0:i]), np.array(nones[i:])])
    
        plt.cla()
        plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%d/%m/%Y')) 
    
        # had to change the locator as well to avoid
        #      RuntimeError: Locator attempting to generate 4018 ticks 
        #      from 729938.0 to 733955.0: exceeds Locator.MAXTICKS
        plt.gca().xaxis.set_major_locator(mdates.MonthLocator())
        plt.ylim(0, 500)
    
        plt.plot(x_vals, y_vals_deaths, label='Deaths')
        plt.legend(loc='upper left')
        plt.tight_layout()
    
    plt.show()
    

    第一个仍然可以使用 DayLocator(),因为大多数帧的数据点很少,因此您不会崩溃硬限制。

    【讨论】:

      【解决方案2】:

      @Patrick 建议的尺寸不一样。但是由于 [0:i] 返回 0 另一个可能的解决方法是:

      import datetime
      import matplotlib.dates as mdates
      import matplotlib.pyplot as plt
      import numpy as np
      import pandas as pd
      
      from matplotlib.animation import FuncAnimation
      
      plt.style.use('fivethirtyeight')
      
      data = pd.read_csv('plot.csv')
      
      x_vals = []
      y_vals_tests_done = []
      y_vals_positive_tests = []
      y_vals_deaths = []
      fig, ax = plt.subplots()
      
      def animate(i):
          x = data['Date']
          y_deaths = data['Deaths']
          x_vals = np.array([datetime.datetime.strptime(d, '%d/%m/%Y').date() for d in x])
          y_vals_deaths = np.array(y_deaths)
      
          plt.cla()
          plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%d/%m/%Y'))
          plt.gca().xaxis.set_major_locator(mdates.DayLocator())
          plt.ylim(0, 500)
      
          plt.plot(x_vals, y_vals_deaths, label='Deaths')
      
          plt.legend(loc='upper left')
      
          plt.tight_layout()
      
      
      ani = FuncAnimation(plt.gcf(), animate, frames=len(data.index) + 1, interval=100, repeat=False)
      plt.show()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多