예제 #1
0
def plotOGimages(waiting_file, bed_file, covid_file):
    print("Generating OG images ...", end=" ")

    makeOGfile()

    # Load data
    waiting_data = np.load(waiting_file, allow_pickle=True)
    bed_data = np.load(bed_file, allow_pickle=True)
    covid_data = np.load(covid_file, allow_pickle=True)

    # Combine names
    bed_names = proc.capitaliseFirst(bed_data[0])
    covid_names = proc.capitaliseFirst(covid_data[0])
    allNames = proc.combineNames(waiting_data[0], bed_names)
    allNames = proc.combineNames(allNames, covid_names)

    for name in allNames:
        figName = proc.makeFigureName(name, "og", "png")
        fig = makeOGimage(name, waiting_data, bed_data, covid_data)
        if fig != None:
            fig.savefig("figures/og/{}".format(figName),
                        bbox_inches='tight',
                        pad_inches=0)
            plt.close(fig)
    print("Done.")
예제 #2
0
def plotBedData(data):
    ''' Plot the number of beds at NHS England Trusts'''

    print("Generating graphs for the number of beds ...", end=" ")

    # Load data
    NHSdata = np.load(data, allow_pickle=True)

    names, dates, beds = NHSdata
    # format name to match waiting data
    names = proc.capitaliseFirst(names)

    #### Plot and save the data ####

    # List of old trusts which have since merged into something else
    oldTrusts = proc.get_all_dict_values(mergered_trusts)
    for i, name in enumerate(names[:]):
        if type(name) == str and not (name in oldTrusts):

            mask = (beds[i, :] != '-')

            if name in mergered_trusts.keys() or sum(mask) >= 4:

                figName = proc.makeFigureName(name, "beds", "svg")
                fig = plotBeds(name, NHSdata)
                fig.savefig("figures/{}".format(figName), bbox_inches='tight')
                plt.close()

    #### Plot trust change pie chart ####
    more, same, fewer = proc.bed_change_per_trust(names, beds, mergered_trusts)

    plt.figure(figsize=(6, 4))
    labels = 'Fewer Beds', 'Same*', 'More Beds'
    sizes = [fewer, same, more]

    colors = ['lightcoral', 'lightgray', 'yellowgreen']
    explode = (0.05, 0.0, 0.0)  # explode 1st slice

    # Plot
    plt.pie(sizes,
            explode=explode,
            labels=labels,
            colors=colors,
            autopct='%1.1f%%',
            shadow=True,
            startangle=140)

    plt.axis('equal')
    plt.tight_layout()
    plt.annotate("* change smaller than 50 beds.", (0.2, -1.2),
                 size=13,
                 color="gray")
    plt.savefig("figures/BedsPieChart.svg")
    plt.close()

    print("Done.")
예제 #3
0
def plotBeds(name, NHSdata):

    if name in mergered_trusts.keys():
        fig = plotMergedBedData(name, NHSdata)

    else:
        names, dates, all_beds = NHSdata

        beds = all_beds[names == name][0]

        dates = dates[beds != "-"]
        beds = beds[beds != "-"]
        # format name to match waiting data
        names = proc.capitaliseFirst(names)
        # rescale large numbers to be in thousands
        if max(beds) > 1000:
            rescale = 1 / 1000
        else:
            rescale = 1

        ylabel = "# of Overnight Beds" + "\n(Thousands)" * (rescale
                                                            == 1 / 1000)

        fig = plt.figure(figsize=(6, 4))
        if min(beds) > 300 and (max(beds) - min(beds)) < min(beds) / 3:
            bax = brokenaxes(ylims=((0, 0.005 * max(beds) * rescale),
                                    (0.95 * min(beds) * rescale,
                                     1.02 * max(beds) * rescale)),
                             hspace=0.08)
            bax.set_ylabel(ylabel, labelpad=50)
        else:
            bax = fig.add_subplot(111)
            bax.set_ylim(0, 1.1 * max(beds) * rescale)
            bax.set_ylabel(ylabel)

        bax.bar(dates, beds * rescale, width=0.18, color=NHSblue)

        xup = int(np.ceil(max(dates))) + 1
        xdown = int(np.floor(min(dates)))
        xint = range(xdown, xup,
                     2 * (xup - xdown > 5) + 1 * (xup - xdown <= 5))

        bax.set_xticks(xint)

    return fig
예제 #4
0
def MakeHomepage(waiting_data, bed_data):
    print("Building homepage...", end=" ")

    # Load data
    names1, _, _, waiting = np.load(waiting_data, allow_pickle=True)
    names2, _, beds = np.load(bed_data, allow_pickle=True)
    names2 = pd.capitaliseFirst(names2)

    allNames = pd.combineNames(names1, names2)
    #print(type(allNames[0]))
    # Make list of hospital names
    hospitalLinksList = []
    for i, name in enumerate(allNames):
        # Check if the trust is in contained in the values of merged_trust
        # i.e. is it an old trust which has since merged into something else.
        oldTrust = name in pd.get_all_dict_values(mergered_trusts)
        if not oldTrust:
            ane_points, bed_points = 0, 0
            merged = name in mergered_trusts.keys()

            if name in names1:
                ane_points = len(
                    waiting[names1 == name][waiting[names1 == name] != '-'])

            if name in names2:
                bed_points = len(
                    beds[names2 == name][beds[names2 == name] != '-'])

            if ane_points >= 10 or bed_points >= 4 or merged:
                url = makeURL(name)
                hospitalLinksList.append(
                    "<li><a href=\"{}\">{}</a></li>\n".format(url, name))

    hospitalLinks = ''.join(hospitalLinksList)
    file = open("index.html", "w")

    file.write(''.join([homeHTML1, hospitalLinks, homeHTML2, footer]))

    file.close()

    print("Done")
예제 #5
0
def plotCovidData(datafile):
    ''' Plot daily covid deaths'''

    print("Generating Covid-19 graphs...", end=" ")

    # Load data

    data = np.load(datafile, allow_pickle=True)
    names = data[0]
    names = proc.capitaliseFirst(names)

    ### Plot and save the data ###
    for i, name in enumerate(names[:]):
        figName = proc.makeFigureName(name, "covid", "svg")

        fig = makeCovidGraph(name, data)

        fig.savefig("figures/{}".format(figName))
        plt.close(fig)

    print("Done.")
예제 #6
0
def makeOGimage(name, waiting_data, bed_data, covid_data):

    matplotlib.rc('font', size=18)
    # load data
    ane_names, dates, attendance, waiting = waiting_data
    bed_names, dates, beds = bed_data
    bed_names = proc.capitaliseFirst(bed_names)
    covid_names, dates, deaths = covid_data
    covid_names = proc.capitaliseFirst(covid_names)

    AnEblock, bedblock, covidblock = whichChunks(name, ane_names, bed_names,
                                                 covid_names, waiting, beds,
                                                 covid_data)
    #print(AnEblock, bedblock)
    if not (AnEblock or bedblock):
        return None

    # Make temp files
    makeOGtempImgs(name, waiting_data, bed_data, covid_data, AnEblock,
                   bedblock, covidblock)

    canvas = np.zeros((630, 1200, 4))

    # solid pale blue canvas
    canvas[:, :, 1] = 0.4
    canvas[:, :, 2] = 1
    canvas[:, :, 3] = 0.1
    fig = plt.figure(figsize=(12, 6.3), dpi=100)
    ax1 = fig.add_axes((0, 0, 1, 1))

    images = []
    # Make and save the figures as png files
    if AnEblock:
        img = imread('og_temp_AnE.png')
        img = addBorder(img)
        images.append(img)

    if bedblock:
        img = imread('og_temp_bed.png')
        img = addBorder(img)
        images.append(img)

    if covidblock:
        img = imread('og_temp_covid.png')
        img = addBorder(img)
        images.append(img)

    if len(images) == 1:
        # Only one plot
        img1 = images[0]

        y1 = 140
        x1 = 260

        canvas[y1:img1.shape[0] + y1, x1:img1.shape[1] + x1, :] = img1

        ax1.imshow(canvas)

    elif len(images) > 1:
        # Two plots

        num_images = len(images)

        # pixels from the top
        yup = 210
        ydown = 50
        ys = np.linspace(yup, ydown, num_images, dtype='int')
        xup = 310
        xdown = 70
        xs = np.linspace(xup, xdown, num_images, dtype='int')
        #print(xs)
        for i in range(num_images):
            canvas[ys[i]:images[i].shape[0] + ys[i],
                   xs[i]:images[i].shape[1] + xs[i], :] = images[i]

        ax1.imshow(canvas)

    else:
        return None

    ax1.set_xticks([])
    ax1.set_yticks([])
    ax1.set_axis_off()
    fig = addLogo(fig)
    # delete temp files
    deleteTempOGFiles()
    return fig
예제 #7
0
def build_trust_pages(waiting_data, beds_data, covid_data, news_file):
    print("Building trust pages...", end=" ")

    # Load data
    names1, dates, attendance, waiting = np.load(waiting_data,
                                                 allow_pickle=True)
    names2, dates, beds = np.load(beds_data, allow_pickle=True)
    names3, dates, covid_deaths = np.load(covid_data, allow_pickle=True)

    # Format and combine all names
    names2 = pd.capitaliseFirst(names2)
    names3 = pd.capitaliseFirst(names3)
    allNames = pd.combineNames(names1, names2)
    allNames = pd.combineNames(allNames, names3)

    # Load news
    newsDict = news.makeNewsDictionary(allNames, news_file)

    # list of old trusts
    oldTrusts = pd.get_all_dict_values(mergered_trusts)
    for i, name in enumerate(allNames):
        #print(name)
        AnEblock, bedblock, covidblock = whichChunks(name, names1, names2,
                                                     names3, attendance, beds,
                                                     covid_deaths)

        if (AnEblock or bedblock or covidblock) and (name not in oldTrusts):

            url = makeURL(name)
            file = open(url, "w")

            if name == "England":
                subTitle = "NHS England Overview"
            else:
                subTitle = name

            meta_HTML = generate_meta(name, AnEblock, bedblock)

            subTitleHTML = '''
            <div class = \"box\">
            \n<h2 class = \"subtitle\">{}</h2>\n'''.format(subTitle)


            tab_HTML = '<div class="tab">' + \
            "<button class=\"tablinks\" onclick=\"openCity(event, 'AnE')\" id=\"defaultOpen\">A&E</button>"*AnEblock + \
            "<button class=\"tablinks\" onclick=\"openCity(event, 'beds')\" id=\"defaultOpen\">Beds</button>"*bedblock + \
            "<button class=\"tablinks\" onclick=\"openCity(event, 'covid')\" id=\"defaultOpen\">Covid-19</button>"*covidblock + \
            "<button class=\"tablinks\" onclick=\"openCity(event, 'news')\" id=\"defaultOpen\">News</button></div>"

            supTextHTML = ""

            if AnEblock:
                supTextHTML += "<div id=\"AnE\" class=\"tabcontent\">" + make_AnE_waiting_block(
                    waiting_data, name) + "</div>\n"

            if bedblock:
                supTextHTML += "<div id=\"beds\" class=\"tabcontent\">" + make_bed_block(
                    beds_data, name) + "</div>\n"
            if covidblock:
                supTextHTML += "<div id=\"covid\" class=\"tabcontent\">" + makeCovidBlock(
                    covid_data, name) + "</div>\n"

            supTextHTML += news.makeNewsBlock(name, newsDict)

            supTextHTML += "</div>\n"

            file.write(''.join([
                headHTML1,
                headHTML2.format(name, meta_HTML), subTitleHTML, tab_HTML,
                supTextHTML, footer2, tab_script
            ]))
            file.close()
    print("Done.")
예제 #8
0
def makeCovidBlock(covid_data, name):
    names, dates, covid_deaths = np.load(covid_data, allow_pickle=True)
    names = pd.capitaliseFirst(names)
    #print(name, covid_deaths[names == name].shape)

    englandDeaths = covid_deaths[names == "England"][0]
    totalEnglandDeaths = sum(englandDeaths)
    weeksEnglandDeaths = sum(englandDeaths[-7::])

    trustDeaths = covid_deaths[names == name][0]
    totalTrustDeaths = sum(trustDeaths)
    weeksTrustDeaths = sum(trustDeaths[-7::])

    # were/was and death/deaths
    were_was = "were" * (trustDeaths[-1] != 1) + "was" * (trustDeaths[-1] == 1)
    death_deaths = "death" + "s" * (trustDeaths[-1] != 1)

    # image html
    figName = pd.makeFigureName(name, "covid", "svg")
    path = "../figures/{}".format(figName)
    imgHTML = "<center><img src=\"{}\" alt=\"{}\"></center>".format(
        path, "Number of Covid-19 related deaths for {}.".format(name))

    # todays date
    todayDate = date.today()
    today = "{}/{}/{}".format(todayDate.day, todayDate.month, todayDate.year)

    compare_to_total = '''
    <p>
    So far, there have been a total of {} Covid-19 related deaths in English hospitals. 
    {} of these {} recorded yesterday and {} over the last seven days. <span style="color:#999999;">Last updated: {}</span>.
    '''.format(format_number(int(totalEnglandDeaths)),
               format_number(int(englandDeaths[-1])), were_was,
               format_number(int(weeksEnglandDeaths)), today)

    if name == "England":
        first_para = '''<p>
        Since the start of the pandemic, there have been {} reported deaths related to Covid-19 in English hospitals.
        There {} {} {} recorded yesterday and {} over the last seven days. <span style="color:#999999;">Last updated: {}</span>.
        </p>'''.format(format_number(int(totalEnglandDeaths)), were_was,
                       format_number(int(englandDeaths[-1])), death_deaths,
                       format_number(int(weeksEnglandDeaths)), today)

    elif totalTrustDeaths == 0:
        first_para = '''
        <p>
        Fortunatlely, there have not yet been any reported deaths in hospital related to Covid-19 at this Trust.
        </p>'''
    elif totalTrustDeaths == 1:
        first_para = '''
        <p>
        There has been one death related to Covid-19 reported at a hospital under this Trust.
        </p>'''
    elif totalTrustDeaths > 1:

        first_para = '''
        <p>
        Unfortunately, since the start of the pandemic in March, there have been {} reported deaths related to Covid-19 at in hospitals under this Trust. There {} {} {} recorded yesterday and a total of {} over the last seven days.
        </p>'''.format(format_number(int(totalTrustDeaths)), were_was,
                       format_number(int(trustDeaths[-1])), death_deaths,
                       format_number(int(weeksTrustDeaths)))

    please_note = '''
    <p>Please note that these figures, particularly the most recent ones, are subject to change as new reports are made. Additionally, these figures do not include deaths outside hospital, such as those in care homes. For additional information, please see the <a href="https://www.england.nhs.uk/statistics/statistical-work-areas/covid-19-daily-deaths/">official NHS page</a> for Covid-19 death statistics.
    </p>
    '''
    call_to_action = '''
    <a href="..\whatnext.html" style = "text-decoration: none;"><div class="action">Call to Action</div></a>
    '''

    chunk = first_para + compare_to_total * (
        name !=
        "England") + imgHTML + please_note + covid_failures + call_to_action

    return chunk
예제 #9
0
def make_bed_block(beds_data, name):
    ''' Generates the chunk of HTML relating to the A&E waiting time data for NHS trust <name>.

    '''
    names, dates, beds = np.load(beds_data, allow_pickle=True)

    names = pd.capitaliseFirst(names)

    i = np.where(names == name)[0]

    figName = pd.makeFigureName(name, "beds", "svg")
    path = "../figures/{}".format(figName)
    imgHTML = "<center><img src=\"{}\" alt=\"{}\"></center>".format(
        path, "Number of available overnight beds for {}.".format(name))

    england_bed_change = beds[0][-1] - beds[0][0]
    england_bed_change_perc = (beds[0][-1] - beds[0][0]) / beds[0][0] * 100

    trusts_with_more, _, trust_with_fewer = pd.bed_change_per_trust(
        names, beds, mergered_trusts)

    # Calculate fractional change
    if name not in mergered_trusts.keys():
        mask = beds[i][0] != "-"
        num_change = beds[i][0][mask][0] - beds[i][0][mask][-1]
        change = num_change / beds[i][0][mask][-1]
    else:
        # Combine merged trust data
        totalBeds = pd.combineBedData(beds, names, name, mergered_trusts)
        mask = totalBeds != "-"

        # calculate change
        num_change = totalBeds[mask][0] - totalBeds[mask][-1]
        change = num_change / totalBeds[mask][-1]

    if i == 0:

        chunk = england_beds.format(format_number(-num_change),
                                    format_number(-num_change), imgHTML,
                                    int(trust_with_fewer),
                                    int(trusts_with_more), brexit_et_al)

    elif change < -0.05 and change > -1:
        start_date = int(np.floor(dates[mask][-1]))
        percentage_change = abs(change) * 100

        chunk = beds_worse.format(name, format_number(-num_change), start_date,
                                  int(percentage_change), imgHTML,
                                  england_bed_change,
                                  int(england_bed_change_perc),
                                  int(trust_with_fewer), int(trusts_with_more),
                                  brexit_et_al)

    elif change == -1:
        # All of the beds are gone
        start_date = int(np.floor(dates[mask][-1]))
        chunk = beds_all_gone.format(name, format_number(-num_change),
                                     start_date, imgHTML, england_bed_change,
                                     int(england_bed_change_perc),
                                     int(trust_with_fewer),
                                     int(trusts_with_more), brexit_et_al)
    elif change > 0.05:
        # Things are better
        start_date = int(np.floor(dates[mask][-1]))
        chunk = beds_better.format(name, int(trusts_with_more), start_date,
                                   format_number(num_change), imgHTML,
                                   england_bed_change,
                                   int(england_bed_change_perc),
                                   int(trust_with_fewer),
                                   int(trusts_with_more), brexit_et_al)

    else:
        # Not much change
        #print(name)

        start_date = int(np.floor(dates[mask][-1]))

        if num_change > 1:
            more_or_less = "{} more beds".format(format_number(
                abs(num_change)))
        elif num_change == 1:
            more_or_less = "exactly 1 more bed"
        elif num_change < -1:
            more_or_less = "{} fewer beds".format(
                format_number(abs(num_change)))
        elif num_change == -1:
            more_or_less = "exactly 1 less bed"
        else:
            more_or_less = "exactly the same number of beds"
        chunk = beds_little_change.format(name, more_or_less, start_date,
                                          imgHTML, england_bed_change,
                                          int(england_bed_change_perc),
                                          int(trust_with_fewer),
                                          int(trusts_with_more), brexit_et_al)

    return chunk