def main(close=True, show=True, save=False):
    """Generate all plots.

    args
        close: close any open plots.
        show: display new plots on screen
        save: write new plots to a file

    returns
        None
    """

    print(f"\nRunning module \"{__name__}\" ...")

    N = c.num_days()
    print("There are a total of %d days" % (N))
    print("The earleiest date is %s" % (c.ind2datetime(0)))
    print("The latest date is %s" % (c.ind2datetime(N-1)))

    if close:
        _num = c.next_fig_num(close)
        close = False

    s.main(close=close, show=show, save=save)
    ts.main(close=close, show=show, save=save)
    rs.main(close=close, show=show, save=save)
    fr.main(close=close, show=show, save=save)
    lp.main(close=close, show=show, save=save)
    hp.main(close=close, show=show, save=save)
    bp.main(close=close, show=show, save=save)
    dr.main(close=close, show=show, save=save)
def main(close=True, show=True, save=False, file_names=("Fig9.pdf",)):
    """Plots to be used in the paper."""

    print(f"\nRunning module \"{__name__}\" ...")

    cases = c.get_data("cases", "US")
    cases_padded, pad_sz = c.extrapolate(cases)

    f0, f1 = 1/7.0, 1/8.0
    y_el_1 = ellip_bf(cases_padded, f0, f1)[pad_sz:-pad_sz]
    H = ellip_spec(f0, f1, 1024)
    y_fft_1 = c.apply_spectrum(cases_padded, H)[pad_sz:-pad_sz]

    start = 40
    print("plot #1 begins on date: %s" % c.ind2datetime(start))
    y_label = lambda x, p: "%.0fk" % (x/1000)
    x = np.arange(0, max(cases[start:].shape), 1)
    dz = np.zeros(len(x))

    num = c.next_fig_num(close)
    fig, (ax3) = plt.subplots(1, 1, figsize=(5, 3.294), num=num)
    ax3.fill_between(x, cases[start:], dz, alpha=0.1, color="#000000", label="daily cases")
    ax3.plot(x, y_el_1[start:], linewidth=1.25, label="elliptic high-pass #1", linestyle=(0,(2,1)))
    ax3.plot(x, y_fft_1[start:], linewidth=1.25, label="FFT high-pass #1", linestyle=(0,(9,9)))
    ax3.set(xlabel='time [days]', ylabel='daily new cases')
    ax3.get_yaxis().set_major_formatter(ticker.FuncFormatter(y_label))
    ax3.grid(True, alpha=0.2)
    ax3.axis([min(x), max(x), -15000, 80000])
    ax3.legend(loc='upper left', prop={'size': 9}, handlelength=2)
    plt.tight_layout()

    if show:
        plt.show(block=False)
    if save:
        c.save_fig(fig, file_names[0])
def main(N=3, close=True, show=True, save=False, file_names=("Fig3.pdf", )):
    """Reconstruct the waveform with 1, 2, or 3 sinusoids. Then search
    for min and max, provided that the harmonics sufficiently big.

    args
        N (int): The number of harmonics to consider (1, 2, or 3).
        close (bool): True if existing plots will be closed.
        show (bool): True if the plot will be displayed on screen.
        save (bool): True if the plot will be saved to file.

    returns
        None
    """

    print(f"\nRunning module \"{__name__}\" ...")

    # some input variables
    start = 70
    end = c.num_days(
    ) - 5  # allowing five days for revisions to be made to the repo
    fft_pts = 2**19
    print("Analysis date range: %s - %s" %
          (c.ind2datetime(start), c.ind2datetime(end)))
    print("Analysis window size: %d" % (end - start))
    print("FFT size: 2^%d = %d points" % (np.log2(fft_pts), fft_pts))

    # The frequencies we are interested in.
    f = np.array([[1 / 7, 2 / 7, 3 / 7]])[:, :N]

    # List of countries to be included in the plots and print out.
    countries = ["US", "Mexico", "Argentina", "United Kingdom", "Brazil"]

    # The datetime at which the integrated derivative begins (time is 12:00 noon).
    t_ref = c.ind2datetime(
        start)  # for FFT derivative plus symbolic integration
    print("Reference time for the integrated derivative: %s" % t_ref)

    num_days = 21  # number of days to synthesize
    step_sz = 20 / (24 * 60 * 60)  #  step size for synthesis (20 seconds)
    xs = np.array([np.arange(0, num_days,
                             step_sz)])  # time-axis for calculating sinusoids
    x = xs[0] + c.days2decimals(t_ref)  # time-axis for plotting sinusoids
    print("Step size for resynthesis: %1.4f seconds" %
          (step_sz * 24 * 60 * 60))

    print()

    # This will be the main data object of interest.
    phf = {"cases": dict(), "deaths": dict()}

    for rt in phf:
        for country in countries:
            data = c.get_data(rt, "global", country=country, state=None)

            d_dt_data = c.deriv_fft(data)[start:end]  # FFT derivative
            Z = np.fft.fft(d_dt_data,
                           n=int(fft_pts)) / fft_pts  # spectrum of derivative

            H_f = Z[(fft_pts * f + 0.5).astype(np.int)]  # freqs. of interest
            theta = np.angle(H_f)  # phase angles
            m = np.abs(H_f)  # magnitudes
            y = (m / (2 * np.pi * f)) * np.sin(
                2 * np.pi * xs.T * f + theta)  # Compute integrated sinusoids
            y_sum = np.sum(y, 1)  # Sum sinusoids

            y_sum = y_sum - (np.max(y_sum) +
                             np.min(y_sum)) / 2  # align vertically for plot
            y_sum = y_sum / max(np.abs(y_sum))  # normalize for plot

            phf[rt][country] = y_sum  # Collect the data

    # Text summary of results
    text_summary(phf, t_ref, xs)

    # Plot
    if show or save:
        make_plot(phf,
                  x,
                  countries,
                  close=close,
                  show=show,
                  save=save,
                  file_name=file_names[0])
Пример #4
0
def main(close=True,
         show=True,
         save=False,
         file_names=(
             "Fig10.pdf",
             "Fig11.pdf",
             "FigUnused_BP.pdf",
         )):
    """Plots to be used in the paper."""

    print(f"\nRunning module \"{__name__}\" ...")

    cases = c.get_data("cases", "US")
    deaths = c.get_data("deaths", "US")

    # Extrapolation
    cases_padded, pad_sz = c.extrapolate(cases)
    deaths_padded, pad_sz = c.extrapolate(deaths)

    numPts = 1024

    # first plot
    wp, ws = [1 / 8.0, 1 / 6.0], [1 / 9.0, 1 / 5.0]
    y_el_1 = ellip_bf(cases_padded, wp, ws)[pad_sz:-pad_sz]  # elliptic
    H_1 = ellip_spec(wp, ws, numPts)
    y_fft_1 = c.apply_spectrum(cases_padded, H_1)[pad_sz:-pad_sz]  # FFT

    start1 = 40
    print("plot #1 begins on date: %s" % c.ind2datetime(start1))
    y1_lables = lambda x, p: "%.0fk" % (x / 1000)
    x1 = np.arange(0, max(cases[start1:].shape), 1)
    dz = np.zeros(len(x1))

    num = c.next_fig_num(close)
    fig1, (ax1) = plt.subplots(1, 1, figsize=(5, 3.294), num=num)
    ax1.fill_between(x1,
                     cases[start1:],
                     dz,
                     alpha=0.1,
                     color="#000000",
                     label="daily deaths")
    ax1.plot(x1,
             y_el_1[start1:],
             linewidth=1.25,
             label="elliptic band-pass #1",
             linestyle=(0, (2, 1)))
    ax1.plot(x1,
             y_fft_1[start1:],
             linewidth=1.25,
             label="FFT band-pass #1",
             linestyle=(0, (9, 9)))
    ax1.get_yaxis().set_major_formatter(ticker.FuncFormatter(y1_lables))
    ax1.grid(True, alpha=0.2)
    ax1.legend(loc='upper left', prop={'size': 9}, handlelength=2)
    ax1.set(xlabel='time [days]')
    ax1.set(ylabel='daily new cases')
    ax1.axis([0, max(y_fft_1[start1:].shape) - 1, -15000, 80000])
    plt.tight_layout()

    # second plot
    wp, ws = [1 / 19, 1 / 9.0], [1 / 21.0, 1 / 8.0]
    y_el_2 = ellip_bf(deaths_padded, wp, ws)[pad_sz:-pad_sz]  # elliptic
    H_2 = ellip_spec(wp, ws, numPts)
    y_fft_2 = c.apply_spectrum(deaths_padded, H_2)[pad_sz:-pad_sz]

    start3 = 100
    print("plot #2 begins on date: %s" % c.ind2datetime(start3))
    y3_lables = lambda x, p: "%.1fk" % (x / 1000)
    x3 = np.arange(0, max(deaths[start3:].shape), 1)
    dz = np.zeros(len(x3))

    num += 1
    fig3, (ax3) = plt.subplots(1, 1, figsize=(5, 3.3), num=num)
    ax3.fill_between(x3,
                     deaths[start3:],
                     dz,
                     alpha=0.1,
                     color="#000000",
                     label="daily deaths")
    ax3.plot(x3,
             y_el_2[start3:],
             linewidth=1.25,
             label="elliptic band-pass #2",
             linestyle=(0, (2, 1)))
    ax3.plot(x3,
             y_fft_2[start3:],
             linewidth=1.25,
             label="FFT band-pass #2",
             linestyle=(0, (9, 9)))
    ax3.get_yaxis().set_major_formatter(ticker.FuncFormatter(y3_lables))
    ax3.grid(True, alpha=0.2)
    ax3.legend(loc='upper right', prop={'size': 9}, handlelength=2)
    ax3.set(xlabel='time [days]')
    ax3.set(ylabel='daily new deaths')
    ax3.axis([0, max(y_fft_2[start3:].shape) - 1, -250, 2500])
    plt.tight_layout()

    # third plot - To check if second plot contains any energy leaking
    # in from bandwidth associated with the seven-day oscillation.
    f = np.arange(0, numPts) / numPts
    d_dt_deaths = c.deriv_fft(deaths)
    Z = np.abs(np.fft.fft(d_dt_deaths, n=int(numPts)) / numPts)
    norm_val = np.max(
        Z[int(numPts * 0.1 +
              0.5):int(numPts * 0.5 +
                       0.5)])  # normalize to max value above 0.1 and 0.5
    Z_deaths = Z / norm_val
    dz = np.zeros(len(f))

    num += 1
    sbStyle = (0, (1, 1))
    pbStyle = (0, (2, 1))
    fig4, (ax4) = plt.subplots(1, 1, figsize=(6, 3.3), num=num)
    ax4.plot(np.array([wp[0]] * 2),
             np.array([-999, 999]),
             '#666666',
             linewidth=1.25,
             linestyle=pbStyle,
             label="\"pass-band\"")
    ax4.plot(np.array([wp[1]] * 2),
             np.array([-999, 999]),
             '#666666',
             linewidth=1.25,
             linestyle=pbStyle)
    ax4.plot(np.array([ws[0]] * 2),
             np.array([-999, 999]),
             '#bbbbbb',
             linewidth=1.25,
             linestyle=sbStyle,
             label="\"stop-band\"")
    ax4.plot(np.array([ws[1]] * 2),
             np.array([-999, 999]),
             '#bbbbbb',
             linewidth=1.25,
             linestyle=sbStyle)
    ax4.fill_between(f,
                     Z_deaths,
                     dz,
                     label="full spectrum",
                     color="#555500",
                     alpha=0.1)
    ax4.plot(f,
             Z_deaths * np.abs(H_2),
             label="plotted spectrum",
             linewidth=1.25,
             linestyle=(0, ()))
    ax4.set(title="The spectrum plotted for \"Band-Pass #2\"",
            xlabel='frequency [1/day]',
            ylabel='magnitude [1]')
    ax4.title.set_size(10)
    ax4.axis([0, 0.5, -0.0, 1.05])
    ax4.legend(loc='upper right',
               prop={'size': 9},
               handlelength=2,
               framealpha=0.92)
    plt.tight_layout()

    if show:
        plt.show(block=False)

    if save:
        c.save_fig(fig1, file_names[0])
        c.save_fig(fig3, file_names[1])
        c.save_fig(fig4, file_names[2])
Пример #5
0
def main(close=True, show=True, save=False, file_names=("Fig1.pdf",)):
    """Create and save frequency spectrum plot for time series (deaths
    and cases)."""

    print(f"\nRunning module \"{__name__}\" ...")

    # some variables
    # countries = ["United Kingdom", "Brazil", "US", "Mexico", "South Africa", "Russia"]
    # countries = ["United Kingdom", "Brazil", "US", "Mexico", "Argentina", "Kenya"]
    countries = ["United Kingdom", "Brazil", "US", "Mexico", "Argentina", "Switzerland"]

    start = 65
    end = c.num_days()
    print("total days: %d, date range: %s, %s" % (end-start, c.ind2datetime(start), c.ind2datetime(end)))
    print("end-start/7 = %f, (end-start)/3.5 = %f" % ((end-start)/7.0, (end-start)/3.5))

    # Create the data
    p_data = dict()
    for country in countries:
        cases = c.get_data("cases", "global", country=country)
        deaths = c.get_data("deaths", "global", country=country)
        f, Z_cases = process_data(cases, start, end)
        f, Z_deaths = process_data(deaths, start, end)
        p_data[country] = {"cases": Z_cases, "deaths": Z_deaths, "f": f}

    # Plot the data
    axis = [0, 0.5, -0.0, 1.05]
    num = c.next_fig_num(close)
    fig = plt.figure(figsize=(10.25, 3), num=num)
    fStyle = (0,(1,1))
    for row in range(2):
        for col in range(3):
            country = countries[col + row*3]
            sub_p_data = p_data[country]
            Z_cases = sub_p_data["cases"]
            Z_deaths = sub_p_data["deaths"]
            f = sub_p_data["f"]

            ax0 = plt.subplot2grid((2, 3), (row, col), colspan=1)
            ax0.plot(np.array([1/7, 1/7]), np.array([-999, 999]), '#bbbbbb', linewidth=1.0, linestyle=fStyle)
            ax0.plot(np.array([2/7, 2/7]), np.array([-999, 999]), '#bbbbbb', linewidth=1.0, linestyle=fStyle)
            ax0.plot(np.array([3/7, 3/7]), np.array([-999, 999]), '#bbbbbb', linewidth=1.0, linestyle=fStyle)
            ax0.plot(f, Z_cases, label="cases", linewidth=1.25)
            ax0.plot(f, Z_deaths, label="deaths", linewidth=1.25, linestyle=(0,(7,1)))
            ax0.set(title=country)
            ax0.title.set_size(10)
            ax0.get_xaxis().set_tick_params(direction='in')
            ax0.get_yaxis().set_tick_params(direction='in')
            ax0.axis(axis)

            if row == 1:
                ax0.set(xlabel='frequency [1/day]')
            else:
                ax0.set_xticklabels('')

            if col == 0:
                ax0.set(ylabel='magnitude')
            else:
                ax0.set_yticklabels('')

            if (row, col) == (0, 2):
                ax0.legend(bbox_to_anchor=(1.05, 1.3), loc='upper right', prop={'size': 9}, handlelength=2, framealpha=0.92)

    plt.tight_layout()

    if show:
        plt.show(block=False)

    if save:
        c.save_fig(fig, file_names[0])
def main(close=True, show=True, save=False, file_names=("Fig6.pdf", "Fig7.pdf", "Fig8.pdf",)):
    """Plots to be used in the paper."""

    print(f"\nRunning module \"{__name__}\" ...")


    deaths = c.get_data("deaths", "US")
    deaths_padded, pad_sz = c.extrapolate(deaths)

    m_ave = seven_day_ave_manual(deaths_padded)[pad_sz-3:-(pad_sz-3)] # moving average

    wp, ws = 1/9, 1/8
    y_el_1 = ellip_bf(deaths_padded, wp, ws)[pad_sz:-pad_sz] # elliptic
    H = ellip_spec(wp, ws, 1024)
    y_fft_1 = c.apply_spectrum(deaths_padded, H)[pad_sz:-pad_sz] # FFT

    wp, ws = 1/21, 1/19
    y_el_2 = ellip_bf(deaths_padded, wp, ws)[pad_sz:-pad_sz] # elliptic
    H = ellip_spec(wp, ws, 1024)
    y_fft_2 = c.apply_spectrum(deaths_padded, H)[pad_sz:-pad_sz] # FFT


    start = 100
    print("plots #1, #2, and #3 begin on date: %s" % c.ind2datetime(start))

    y_lables = lambda x, p: "%.1fk" % (x/1000)
    x = np.arange(0, max(deaths[start:].shape), 1)
    dz = np.zeros(len(x))

    num = c.next_fig_num(close)
    fig1, (ax1) = plt.subplots(1, 1, figsize=(5, 3), num=num)
    ax1.fill_between(x, deaths[start:], dz, alpha=0.1, color="#000000", label="daily deaths")
    ax1.plot(x, m_ave[start:], linewidth=1.25, label="moving average")
    ax1.set(xlabel='time [days]', ylabel='daily new deaths')
    ax1.get_yaxis().set_major_formatter(ticker.FuncFormatter(y_lables))
    ax1.grid(True, alpha=0.2)
    ax1.axis([min(x), max(x), 0, 2500])
    ax1.legend(loc='upper right', prop={'size': 9}, handlelength=2)
    plt.tight_layout()

    y_lables = lambda x, p: "%.1fk" % (x/1000)
    x = np.arange(0, max(deaths[start:].shape), 1)
    dz = np.zeros(len(x))

    num += 1
    fig2, (ax2) = plt.subplots(1, 1, figsize=(5, 3), num=num)
    ax2.fill_between(x, deaths[start:], dz, alpha=0.1, color="#000000", label="daily deaths")
    ax2.plot(x, y_el_1[start:], linewidth=1.25, label="elliptic low-pass #1", linestyle=(0,(2,1)))
    ax2.plot(x, y_fft_1[start:], linewidth=1.25, label="FFT low-pass #1", linestyle=(0,(9,9)))
    ax2.set(xlabel='time [days]', ylabel='daily new deaths')
    ax2.get_yaxis().set_major_formatter(ticker.FuncFormatter(y_lables))
    ax2.grid(True, alpha=0.2)
    ax2.axis([min(x), max(x), 0, 2500])
    ax2.legend(loc='upper right', prop={'size': 9}, handlelength=2)
    plt.tight_layout()

    y_lables = lambda x, p: "%.1fk" % (x/1000)
    x = np.arange(0, max(deaths[start:].shape), 1)
    dz = np.zeros(len(x))

    num += 1
    fig4, (ax4) = plt.subplots(1, 1, figsize=(5, 3), num=num)
    ax4.fill_between(x, deaths[start:], dz, alpha=0.1, color="#000000", label="daily deaths")
    ax4.plot(x, y_el_2[start:], linewidth=1.25, label="elliptic low-pass #2", linestyle=(0,(2,1)))
    ax4.plot(x, y_fft_2[start:], linewidth=1.25, label="FFT low-pass #2", linestyle=(0,(9,9)))
    ax4.set(xlabel='time [days]', ylabel='daily new deaths')
    ax4.get_yaxis().set_major_formatter(ticker.FuncFormatter(y_lables))
    ax4.grid(True, alpha=0.2)
    ax4.axis([min(x), max(x), 0, 2500])
    ax4.legend(loc='upper right', prop={'size': 9}, handlelength=2)
    plt.tight_layout()

    if show:
        plt.show(block=False)
    if save:
        c.save_fig(fig1, file_names[0])
        c.save_fig(fig2, file_names[1])
        c.save_fig(fig4, file_names[2])
Пример #7
0
def main(close=True,
         show=True,
         save=False,
         rt="deaths",
         region="global",
         country="Brazil",
         state=None,
         file_names=("Fig2.pdf", )):
    """time segment FFT analysis.

    keyword args
        close: close plots (boolean)
        show: show plots (boolean)
        save: save plots (boolean)
        rt: record type ("deaths" or "cases")
        region: global or US
        country: country name
        state: name of US State

    returns
        None
    """

    print(f"\nRunning module \"{__name__}\" ...")

    start = 35
    data = c.get_data(rt, region, country=country, state=state)
    data = data[start:]
    data_d_dt = c.deriv_fft(data)

    winSz = 25

    print("time-spectrum start date: %s" % (c.ind2datetime(start)))
    print("initial window center: %s" % (c.ind2datetime(start + winSz / 2)))
    print("final window center: %s" %
          (c.ind2datetime(start + len(data) - 1 - winSz / 2)))
    print("sliding window size: %d" % (winSz))

    N = 1024  # % pts in FFT
    numSamps = len(data)
    numHops = numSamps - winSz  # 1 sample hops (sliding window)

    # set frequency range used for plotting
    minFreq = 0.0
    maxFreq = 0.5
    minFreq_ind = int(N * minFreq + 0.5)
    maxFreq_ind = int(N * maxFreq + 0.5)

    # set frequency range used for normnalization
    normCutMinFreq = 0.1
    normCutMaxFreq = 0.5
    normCutMinFreq_ind = int(N * normCutMinFreq + 0.5)
    normCutMaxFreq_ind = int(N * normCutMaxFreq + 0.5)

    Z = np.zeros([numHops, maxFreq_ind - minFreq_ind])
    Z_hanning = np.zeros([numHops, maxFreq_ind - minFreq_ind])
    Z_d_dt = np.zeros([numHops, maxFreq_ind - minFreq_ind])

    b_start = 0
    b_stop = winSz

    for n in range(numHops):
        xr = data[b_start:b_stop]
        X = np.fft.fft(xr, n=N) / N
        X = np.abs(X[:N // 2])
        Z[n] = X[minFreq_ind:maxFreq_ind] / np.max(
            X[normCutMinFreq_ind:normCutMaxFreq_ind])

        xr = data[b_start:b_stop]
        X = np.fft.fft(xr * np.hanning(winSz), n=N) / N
        X = np.abs(X[:N // 2])
        Z_hanning[n] = X[minFreq_ind:maxFreq_ind] / np.max(
            X[normCutMinFreq_ind:normCutMaxFreq_ind])

        xr = data_d_dt[b_start:b_stop]
        X = np.fft.fft(xr, n=N) / N
        X = np.abs(X[:N // 2])
        Z_d_dt[n] = X[minFreq_ind:maxFreq_ind] / np.max(
            X[normCutMinFreq_ind:normCutMaxFreq_ind])

        b_start += 1
        b_stop += 1

    # clip values that exceed unity.
    Z = np.clip(Z, 0, 1)
    Z_hanning = np.clip(Z_hanning, 0, 1)
    Z_d_dt = np.clip(Z_d_dt, 0, 1)

    # interp = None # smallest size
    interp = 'sinc'
    colors = cm.Blues_r
    # colors = cm.magma # largest size, percetual color map
    # colors = cm.gray # smallest size

    xMin = winSz * 0.5
    xMax = winSz * 0.5 + Z.shape[0]

    num = c.next_fig_num(close)
    fig = plt.figure(figsize=(10.25, 2.3), num=num)

    # --------------------------------------------------------------
    ax0 = plt.subplot2grid((1, 3), (0, 0))
    ax0.imshow(np.flipud(Z.transpose(1, 0)),
               interpolation=interp,
               cmap=colors,
               extent=(xMin, xMax, minFreq, maxFreq),
               aspect='auto')
    ax0.set(xlabel='time [days]',
            title="Square Window",
            ylabel='frequency [1/day]')
    ax0.title.set_size(10)
    ax0.yaxis.set_major_locator(plt.MultipleLocator(0.1))

    # --------------------------------------------------------------
    ax1 = plt.subplot2grid((1, 3), (0, 1))
    ax1.imshow(np.flipud(Z_hanning.transpose(1, 0)),
               interpolation=interp,
               cmap=colors,
               extent=(xMin, xMax, minFreq, maxFreq),
               aspect='auto')
    ax1.set(xlabel='time [days]', title="Hanning Window")
    ax1.title.set_size(10)
    ax1.set_yticklabels('')
    ax1.tick_params(axis=u'y', which=u'both', length=0)

    # --------------------------------------------------------------
    ax2 = plt.subplot2grid((1, 3), (0, 2))
    ax2.imshow(np.flipud(Z_d_dt.transpose(1, 0)),
               interpolation=interp,
               cmap=colors,
               extent=(xMin, xMax, minFreq, maxFreq),
               aspect='auto')
    ax2.set(xlabel='time [days]', title="Square Window of Derivative")
    ax2.title.set_size(10)
    ax2.set_yticklabels('')
    ax2.tick_params(axis=u'y', which=u'both', length=0)

    plt.tight_layout()

    if show:
        plt.show(block=False)

    if save:
        c.save_fig(fig, file_names[0])