def eurominder_explorer():
    """Generate interactive data exploration tool

    Output is an html page, rendered to 'eurominder_explorer.html' in the output directory.

    Data structure (only relevant items are shown below):

    .. code-block:: none

        {
            "nuts2Features": [{"geometry": [<boundary geometry>],
                               "properties": { "NUTS_ID": "AT11" } },
                              {"geometry": [<boundary geometry>],
                               "properties": { "NUTS_ID": "AT12" } },
                              ...],

            "regionNames": {"AT11": "Burgenland",
                            "AT13": "Wien",
                            ...
                           },

            "indicatorDescriptions": {"000005": "some description",
                                      "000010": "another description",
                                      ...},

            "indicators": [ {"key": "AT11",
                             "000005 2010": 37.0
                             "000005 2011": 38.0
                             ...
                             "000010 2010": 1234.0
                             "000010 2011": 1235.0
                             ...
                             "Mean temperature (C) Apr-Sep": 16.0,
                             "Mean temperature (C) Oct-Mar": 9.0,
                             ...
                             },
                            {"key": "AT12",
                             "000005 2010: 19.0,
                             ..
                            },
                            ...
                         ]

            "ranges": {"000005": [10, 20],
                       "000010": [1234, 5678],
                       ...,
                       "Mean temperature (C) Apr-Sep": 16.0,
                       "Mean temperature (C) Oct-Mar": 9.0,
                       ...
                       },

            "years": ["1999", "2000", ...],

        }
    """
    # switch off some pandas warnings
    import pandas as pd
    pd.options.mode.chained_assignment = None

    # page template
    template = jenv.get_template("eurominder_explorer.html")

    # container for template context
    context = dict()

    # plot data
    data = dict()

    # a database client/session to run queries in
    cl = client.get_client()
    session = cl.create_session()

    #
    # query data
    #

    # get region names and keys
    query = session.query(models.NUTS2Region.key,
                          models.NUTS2Region.name).all()
    data['regionNames'] = {t[0]: t[1] for t in query}

    # get indicator descriptions
    query = session.query(models.EuroStatIndicator.number,
                          models.EuroStatIndicator.description)
    data['indicatorDescriptions'] = {t[0]: t[1] for t in query}

    # build options for HTML selector for selecting which indicator to show
    context['y_field_selector_options'] = ''
    context['x_field_selector_options'] = ''
    for i_field, number in enumerate(sorted(data['indicatorDescriptions'].keys())):
        description = data['indicatorDescriptions'][number]

        # first field is default option for y selector, second field for x selector
        y_selected = " selected=\"selected\"" if i_field == 0 else ""
        x_selected = " selected=\"selected\"" if i_field == 1 else ""

        context['y_field_selector_options'] += "<option value=\"{:s}\" {:s}>{:s}</option>" \
                                               "".format(number, y_selected, description)
        context['x_field_selector_options'] += "<option value=\"{:s}\" {:s}>{:s}</option>" \
                                               "".format(number, x_selected, description)

    # get all eurostats data
    query = session.query(models.EuroStatValue.value,
                          models.EuroStatValue.year,
                          models.EuroStatIndicator.number,
                          models.NUTS2Region.key) \
        .join(models.EuroStatIndicator) \
        .join(models.NUTS2Region)
    eurostat = cl.df_query(query)

    # reformat to list of value dicts per region, as described above
    data['indicators'] = []
    for region_key, region_data in eurostat.groupby('key'):
        region_data['str_id'] = region_data['number'] + ' ' + region_data['year'].apply(lambda x: str(x))
        value_dict = region_data.set_index('str_id')['value'].to_dict()
        value_dict['key'] = region_key
        data['indicators'].append(value_dict)

    # store min/max values per indicator across all years, to keep plot scales fixed on playback
    data['ranges'] = dict()
    for number, indicator_data in eurostat.groupby('number'):
        data['ranges'][number] = [indicator_data['value'].min(), indicator_data['value'].max()]

    # build options for year selector (also store options in a list, for playback control)
    data['years'] = sorted([str(y) for y in eurostat['year'].unique()])
    context['year_selector_options'] = ''
    for year in data['years']:
        year_selected = " selected=\"selected\"" if year == "2010" else ""
        context['year_selector_options'] += "<option {:s}>{:s}</option>".format(year_selected, year)

    # query climate data
    query = session.query(models.ClimateValue.value,
                          models.ClimateIndicator.description,
                          models.NUTS2Region.key) \
        .join(models.ClimateIndicator) \
        .join(models.NUTS2Region)
    climate = cl.df_query(query).set_index('key')

    # inject data into 'indicators' records
    for record in data['indicators']:
        try:
            # index by a list of keys to be sure to get back a DataFrame even for one matching record
            cdata = climate.loc[[record['key']]]
        except KeyError:
            # no data available
            continue

        for description, value in cdata.set_index('description')['value'].iteritems():
            record[description] = value

    # sorted list of climate descriptions
    data['climateDescriptions'] = sorted(list(climate['description'].unique()))

    # store ranges of climate indicators, lump summer and winter together (by stripping season indicator)
    # to get comparable scales
    climate['variable_description'] = climate['description'].map(lambda s: ' '.join(s.split()[:-1]))
    for variable_description, indicator_data in climate.groupby('variable_description'):
        r = [indicator_data['value'].min(), indicator_data['value'].max()]
        data['ranges'][variable_description + pipeline.CLIMATE_SEASON_SUFFIXES['winter']] = r
        data['ranges'][variable_description + pipeline.CLIMATE_SEASON_SUFFIXES['summer']] = r

    # inject GeoJSON polygons
    with open(pipeline.NUTS2GeoJSONInputFile().input_file) as in_file:
        nuts2_boundaries = json.load(in_file)
    data['nuts2Features'] = nuts2_boundaries['features']

    #
    # render template
    #

    # inject data
    context['data'] = json.dumps(data, indent=4)

    out_file = path.join(out_dir, "eurominder_explorer.html")
    html_content = template.render(**context)
    with open(out_file, 'w') as f:
        f.write(html_content)

    # done, clean up
    session.close()
def eurominder_explorer ( ) : import pandas as pd pd . options . mode . chained_assignment = None template = jenv . get_template ( "eurominder_explorer.html" ) context = dict ( ) data = dict ( ) cl = client . get_client ( ) session = cl . create_session ( ) query = session . query ( models . NUTS2Region . key , models . NUTS2Region . name ) . all ( ) data [ 'regionNames' ] = { t [ 0 ] : t [ 1 ] for t in query } query = session . query ( models . EuroStatIndicator . number , models . EuroStatIndicator . description ) data [ 'indicatorDescriptions' ] = { t [ 0 ] : t [ 1 ] for t in query } context [ 'y_field_selector_options' ] = '' context [ 'x_field_selector_options' ] = '' for i_field , number in enumerate ( sorted ( data [ 'indicatorDescriptions' ] . keys ( ) ) ) : description = data [ 'indicatorDescriptions' ] [ number ] y_selected = " selected=\"selected\"" if i_field == 0 else "" x_selected = " selected=\"selected\"" if i_field == 1 else "" context [ 'y_field_selector_options' ] += "<option value=\"{:s}\" {:s}>{:s}</option>" "" . format ( number , y_selected , description ) context [ 'x_field_selector_options' ] += "<option value=\"{:s}\" {:s}>{:s}</option>" "" . format ( number , x_selected , description ) query = session . query ( models . EuroStatValue . value , models . EuroStatValue . year , models . EuroStatIndicator . number , models . NUTS2Region . key ) . join ( models . EuroStatIndicator ) . join ( models . NUTS2Region ) eurostat = cl . df_query ( query ) data [ 'indicators' ] = [ ] for region_key , region_data in eurostat . groupby ( 'key' ) : region_data [ 'str_id' ] = region_data [ 'number' ] + ' ' + region_data [ 'year' ] . apply ( lambda x : str ( x ) ) value_dict = region_data . set_index ( 'str_id' ) [ 'value' ] . to_dict ( ) value_dict [ 'key' ] = region_key data [ 'indicators' ] . append ( value_dict ) data [ 'ranges' ] = dict ( ) for number , indicator_data in eurostat . groupby ( 'number' ) : data [ 'ranges' ] [ number ] = [ indicator_data [ 'value' ] . min ( ) , indicator_data [ 'value' ] . max ( ) ] data [ 'years' ] = sorted ( [ str ( y ) for y in eurostat [ 'year' ] . unique ( ) ] ) context [ 'year_selector_options' ] = '' for year in data [ 'years' ] : year_selected = " selected=\"selected\"" if year == "2010" else "" context [ 'year_selector_options' ] += "<option {:s}>{:s}</option>" . format ( year_selected , year ) query = session . query ( models . ClimateValue . value , models . ClimateIndicator . description , models . NUTS2Region . key ) . join ( models . ClimateIndicator ) . join ( models . NUTS2Region ) climate = cl . df_query ( query ) . set_index ( 'key' ) for record in data [ 'indicators' ] : try : cdata = climate . loc [ [ record [ 'key' ] ] ] except KeyError : continue for description , value in cdata . set_index ( 'description' ) [ 'value' ] . iteritems ( ) : record [ description ] = value data [ 'climateDescriptions' ] = sorted ( list ( climate [ 'description' ] . unique ( ) ) ) climate [ 'variable_description' ] = climate [ 'description' ] . map ( lambda s : ' ' . join ( s . split ( ) [ : - 1 ] ) ) for variable_description , indicator_data in climate . groupby ( 'variable_description' ) : r = [ indicator_data [ 'value' ] . min ( ) , indicator_data [ 'value' ] . max ( ) ] data [ 'ranges' ] [ variable_description + pipeline . CLIMATE_SEASON_SUFFIXES [ 'winter' ] ] = r data [ 'ranges' ] [ variable_description + pipeline . CLIMATE_SEASON_SUFFIXES [ 'summer' ] ] = r with open ( pipeline . NUTS2GeoJSONInputFile ( ) . input_file ) as in_file : nuts2_boundaries = json . load ( in_file ) data [ 'nuts2Features' ] = nuts2_boundaries [ 'features' ] context [ 'data' ] = json . dumps ( data , indent = 4 ) out_file = path . join ( out_dir , "eurominder_explorer.html" ) html_content = template . render ( ** context ) with open ( out_file , 'w' ) as f : f . write ( html_content ) session . close ( )
Generate interactive data exploration tool

    Output is an html page, rendered to 'eurominder_explorer.html' in the output directory.

    Data structure (only relevant items are shown below):

    .. code-block:: none

        {
            "nuts2Features": [{"geometry": [<boundary geometry>],
                               "properties": { "NUTS_ID": "AT11" } },
                              {"geometry": [<boundary geometry>],
                               "properties": { "NUTS_ID": "AT12" } },
                              ...],

            "regionNames": {"AT11": "Burgenland",
                            "AT13": "Wien",
                            ...
                           },

            "indicatorDescriptions": {"000005": "some description",
                                      "000010": "another description",
                                      ...},

            "indicators": [ {"key": "AT11",
                             "000005 2010": 37.0
                             "000005 2011": 38.0
                             ...
                             "000010 2010": 1234.0
                             "000010 2011": 1235.0
                             ...
                             "Mean temperature (C) Apr-Sep": 16.0,
                             "Mean temperature (C) Oct-Mar": 9.0,
                             ...
                             },
                            {"key": "AT12",
                             "000005 2010: 19.0,
                             ..
                            },
                            ...
                         ]

            "ranges": {"000005": [10, 20],
                       "000010": [1234, 5678],
                       ...,
                       "Mean temperature (C) Apr-Sep": 16.0,
                       "Mean temperature (C) Oct-Mar": 9.0,
                       ...
                       },

            "years": ["1999", "2000", ...],

        }