コード例 #1
0
def main():
    # get the latests database files as a CSV
    try:
        pathToCSV_owid = CovidCasesOWID.download_CSV_file()
        pathToCSV_who = CovidCasesWHO.download_CSV_file()
    except FileNotFoundError:
        # print an error message
        print('Unable to download the database. Try again later.')
        return

    # some benchmarking
    start = time.time()
    # create instances
    covidCases_owid = CovidCasesOWID(pathToCSV_owid)
    covidCases_who = CovidCasesWHO(pathToCSV_who)
    # create tuples of instances and country codes
    objList = [covidCases_owid, covidCases_who]

    # just in case we want to use some optionals
    numCasesSince = 1000
    lastN = 90
    # the list of comma separated geoIDs
    countryList = 'DE, GB, FR, ES, IT, CH, AT, EL, NA'
    # get the combined dataframe
    #df = CovidCases.create_combined_dataframe_by_geoid_string_list(objList, countryList)
    #df = CovidCases.create_combined_dataframe_by_geoid_string_list(objList, countryList, lastNdays=lastN)
    df = CovidCases.create_combined_dataframe_by_geoid_string_list(
        objList, countryList, sinceNcases=numCasesSince)

    # the width for a filter
    width = 7
    for obj in objList:
        # add lowpass filtered DailyCases
        df = obj.add_lowpass_filter_for_attribute(df, 'DailyCases', width)
        # add r0
        df = obj.add_r0(df)
        # add lowpass filtered R
        df = obj.add_lowpass_filter_for_attribute(df, "R", 7)

    # benchmarking
    end = time.time()
    print(str((end - start)) + 's')
    # plot it
    plot_the_data(df)
    # show the plot
    plt.show()
    # plot a map
    #plot_map(covidCases_who)
    return
コード例 #2
0
    def get_pygal_oceania_geoid_list():
        """Returns a list of GeoIDs of Oceanian countries that are available in PayGal and 
        the WHO data. 
        Be aware:
        Not all countries of the WHO are available in PayGal and some names are different 
        (GB in PyGal = UK in WHO, GR in PyGal = EL in WHO). PyGal uses lower case and WHO
        upper case. 

        Returns:
            list: List of strings of GeoID's
        """
        # just the main countries for a map
        geoIDs = re.split(
            r',\s*',
            CovidCases.get_pygal_oceania_geoid_string_list().upper())
        return geoIDs
コード例 #3
0
    def generate_plot(self,
                      geo_ids,
                      wanted_attrib,
                      log=False,
                      last_n=-1,
                      since_n=-1,
                      bar=False):
        """
        Generates a plot for given GeoIds and returns it in form of a byteIO stream
        Parameters:
            geo_ids: [String] -> countries that should be plotted
            wanted_attrib: String -> the field you want to plot, e.g. Cases
            log: bool -> should the plot be logarithmic
            last_n: int -> plot the last n days, if not further specified all available data is plotted
            since_n: int -> plot since the nth case, if not further specified all available data is plotted
        """
        # load the cases
        csv_file = CovidCases.download_CSV_file()
        self.covid_cases = CovidCases(csv_file)

        # try to collect the data for given geoIds, if a wrong geoId is passed, the operation will abort with a 400
        # bad request error
        try:
            df = self.covid_cases.get_country_data_by_geoid_list(
                geo_ids, lastNdays=last_n, sinceNcases=since_n)
        except IndexError:
            raise HTTPException(status_code=400, detail="Couldn't load data")

        # if the wanted attribute is one that need to be calculated, calculate it
        if wanted_attrib == Attributes.R or Attributes.R7:
            df = self.covid_cases.add_r0(df)
        if wanted_attrib == Attributes.R7:
            df = self.covid_cases.add_lowpass_filter_for_attribute(df, 'R', 7)
        if wanted_attrib == Attributes.DailyCases7:
            df = self.covid_cases.add_lowpass_filter_for_attribute(
                df, 'DailyCases', 7)
        if wanted_attrib == Attributes.DailyDeaths7:
            df = self.covid_cases.add_lowpass_filter_for_attribute(
                df, 'DailyDeaths', 7)
        if wanted_attrib == Attributes.DoublingTime7:
            df = self.covid_cases.add_lowpass_filter_for_attribute(
                df, 'DoublingTime', 7)
        if wanted_attrib == Attributes.Incidence7DayPer100Kpopulation:
            df = self.covid_cases.add_incidence_7day_per_100Kpopulation(df)

        # concat to one DataFrame and set date
        df[['Date']] = pd.to_datetime(df['Date'], format='%d/%m/%Y')
        # create pivot table with all needed values, if the x-axis shows a timedelta with days since the nth case the index
        # has to change
        pldf = df.pivot_table(values=wanted_attrib.name, index='Date', columns='Country') if since_n == -1 \
            else df.pivot_table(values=wanted_attrib.name, index=df.index, columns='Country')

        # use the PlotterBuilder to set up the plot
        builder = (
            PlotterBuilder(wanted_attrib)
            #.set_title(re.sub(r"([a-z])([A-Z])", r"\g<1> \g<2>", wanted_attrib.name))
            .set_title(AttributeTitles[wanted_attrib.value].value).set_grid())
        if log:
            builder.set_log()
        if since_n != -1:
            # if the plot has a timedelta on the x-axis, the label has to be reset
            builder.set_axis_labels(xlabel="Days since case " + str(since_n))
            builder.set_xaxis_index()
        # generate plot
        fig, ax = builder.build()
        if bar:
            pldf.plot(ax=ax, kind='bar')
        else:
            pldf.plot(ax=ax)
            ax.grid()
        # write image to io stream
        byte_io = io.BytesIO()
        plt.savefig(byte_io, dpi=fig.dpi)
        byte_io.seek(0)

        return byte_io
コード例 #4
0
class Rest_API:
    def generate_plot(self,
                      geo_ids,
                      wanted_attrib,
                      log=False,
                      last_n=-1,
                      since_n=-1,
                      bar=False):
        """
        Generates a plot for given GeoIds and returns it in form of a byteIO stream
        Parameters:
            geo_ids: [String] -> countries that should be plotted
            wanted_attrib: String -> the field you want to plot, e.g. Cases
            log: bool -> should the plot be logarithmic
            last_n: int -> plot the last n days, if not further specified all available data is plotted
            since_n: int -> plot since the nth case, if not further specified all available data is plotted
        """
        # load the cases
        csv_file = CovidCases.download_CSV_file()
        self.covid_cases = CovidCases(csv_file)

        # try to collect the data for given geoIds, if a wrong geoId is passed, the operation will abort with a 400
        # bad request error
        try:
            df = self.covid_cases.get_country_data_by_geoid_list(
                geo_ids, lastNdays=last_n, sinceNcases=since_n)
        except IndexError:
            raise HTTPException(status_code=400, detail="Couldn't load data")

        # if the wanted attribute is one that need to be calculated, calculate it
        if wanted_attrib == Attributes.R or Attributes.R7:
            df = self.covid_cases.add_r0(df)
        if wanted_attrib == Attributes.R7:
            df = self.covid_cases.add_lowpass_filter_for_attribute(df, 'R', 7)
        if wanted_attrib == Attributes.DailyCases7:
            df = self.covid_cases.add_lowpass_filter_for_attribute(
                df, 'DailyCases', 7)
        if wanted_attrib == Attributes.DailyDeaths7:
            df = self.covid_cases.add_lowpass_filter_for_attribute(
                df, 'DailyDeaths', 7)
        if wanted_attrib == Attributes.DoublingTime7:
            df = self.covid_cases.add_lowpass_filter_for_attribute(
                df, 'DoublingTime', 7)
        if wanted_attrib == Attributes.Incidence7DayPer100Kpopulation:
            df = self.covid_cases.add_incidence_7day_per_100Kpopulation(df)

        # concat to one DataFrame and set date
        df[['Date']] = pd.to_datetime(df['Date'], format='%d/%m/%Y')
        # create pivot table with all needed values, if the x-axis shows a timedelta with days since the nth case the index
        # has to change
        pldf = df.pivot_table(values=wanted_attrib.name, index='Date', columns='Country') if since_n == -1 \
            else df.pivot_table(values=wanted_attrib.name, index=df.index, columns='Country')

        # use the PlotterBuilder to set up the plot
        builder = (
            PlotterBuilder(wanted_attrib)
            #.set_title(re.sub(r"([a-z])([A-Z])", r"\g<1> \g<2>", wanted_attrib.name))
            .set_title(AttributeTitles[wanted_attrib.value].value).set_grid())
        if log:
            builder.set_log()
        if since_n != -1:
            # if the plot has a timedelta on the x-axis, the label has to be reset
            builder.set_axis_labels(xlabel="Days since case " + str(since_n))
            builder.set_xaxis_index()
        # generate plot
        fig, ax = builder.build()
        if bar:
            pldf.plot(ax=ax, kind='bar')
        else:
            pldf.plot(ax=ax)
            ax.grid()
        # write image to io stream
        byte_io = io.BytesIO()
        plt.savefig(byte_io, dpi=fig.dpi)
        byte_io.seek(0)

        return byte_io

    def setup_routes(self, app: FastAPI):
        """
        Setup of the route. The url has to be in the form:
        /api/data/<country codes comma separated>/<attribute to be plotted>
            ?log=(True or False)[&lastN=X if you want to plot lastNdays][&sinceN=X if you want to plot since the Nth case]
        """

        # setting up routes and implement methods
        @app.get('/api/data/{countries}/{wanted_attrib}')
        def get_data(countries: str,
                     wanted_attrib: Attributes,
                     sinceN: Optional[int] = None,
                     lastN: Optional[int] = None,
                     log: Optional[bool] = None,
                     bar: Optional[bool] = None):
            """
            Returns a png image of the plotted Attribute (see Attributes) for a list of Countries(comma seperated). The URL needs to be in the following form:
            **/api/data/<country codes comma separated>/<attribute to be plotted>
            ?log=(True or False)[&lastN=X if you want to plot lastNdays][&sinceN=X if you want to plot since the Nth case]**
            SinceN and lastN plots the data starting from the given case or just the lastN days. Log is a boolean value that converts the y-scale to the logarithmic unit.
            """
            # read the geoIds and plot the file
            geo_ids = re.split(r",\s*", countries.upper())
            file = self.generate_plot(geo_ids,
                                      wanted_attrib,
                                      last_n=lastN if lastN != None else -1,
                                      log=log,
                                      since_n=sinceN if sinceN != None else -1,
                                      bar=bar)

            # return the created stream as png image
            return StreamingResponse(file, media_type="image/png")
コード例 #5
0
import datetime
from datetime import date
import math
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import pandas as pd
from CovidCases import CovidCases
from PlotterBuilder import PlotterBuilder

# get the latests database file as a CSV
try:
    pathToCSV = CovidCases.download_CSV_file()
except FileNotFoundError:
    pathToCSV = "data/db.csv"
    print('Unable to download the database. Try again later.')
except IOError:
    pathToCSV = "data/db.csv"
    print('Error writing file.')

# the list of comma separated geoIDs
countryList = 'DE, IT, ES, UK, FR, AT, NL'

# just in case we want to use some optionals
numCasesStart = 500
lastN = 40

# create an instance
covidCases = CovidCases(pathToCSV)
# get the dataframe for our countries
#df = covidCases.get_country_data_by_geoid_string_list(countryList, sinceNcases=numCasesStart)
df = covidCases.get_country_data_by_geoid_string_list(countryList,