Windturbines#

import holoviews as hv
import panel as pn
import pandas as pd

pn.extension('vizzu', 'tabulator', design='material', template='material')
import hvplot.pandas

Load data#

windturbines = pn.state.as_cached(
    'windturbines',
    pd.read_parquet,
    path='https://datasets.holoviz.org/windturbines/v1/windturbines.parq'
)

windturbines.head()
case_id faa_ors faa_asn usgs_pr_id eia_id t_state t_county t_fips p_name p_year p_tnum p_cap t_manu t_model t_cap t_hh t_rd t_rsa t_ttlh retrofit retrofit_year t_conf_atr t_conf_loc t_img_date t_img_srce xlong ylat easting northing
0 3072661 None None 5149.0 52161.0 CA Kern County 6029 251 Wind 1987.0 194 18.43 Vestas None 95.0 NaN NaN NaN NaN 0 NaN 2 3 2018-05-08 Digital Globe -118.363762 35.077908 -1.317619e+07 4.174474e+06
1 3072695 None None 5143.0 52161.0 CA Kern County 6029 251 Wind 1987.0 194 18.43 Vestas None 95.0 NaN NaN NaN NaN 0 NaN 2 3 2018-05-08 Digital Globe -118.364410 35.077435 -1.317627e+07 4.174409e+06
2 3072704 None None 5146.0 52161.0 CA Kern County 6029 251 Wind 1987.0 194 18.43 Vestas None 95.0 NaN NaN NaN NaN 0 NaN 2 3 2018-05-08 Digital Globe -118.364197 35.077644 -1.317624e+07 4.174438e+06
3 3063272 19-028134 2014-WTE-4084-OE NaN NaN IA Story County 19169 30 MW Iowa DG Portfolio 2017.0 10 30.00 Nordex AW125/3000 3000.0 87.5 125.0 12271.85 150.0 0 NaN 3 3 2017-04-24 Digital Globe -93.430367 42.028233 -1.040062e+07 5.165210e+06
4 3053390 19-028015 2015-WTE-6386-OE NaN NaN IA Boone County 19015 30 MW Iowa DG Portfolio 2017.0 10 30.00 Nordex AW125/3000 3000.0 87.5 125.0 12271.85 150.0 0 NaN 3 3 2017-06-01 Digital Globe -93.700424 41.977608 -1.043068e+07 5.157626e+06

Plot data#

def data(df, groupby, quant):
    if quant == 'Count':
        return df.value_counts(groupby).to_frame(name='Count').sort_index().reset_index().iloc[:50]
    else:
        return df.groupby(groupby)[quant].sum().reset_index().iloc[:50]

def config(chart_type, groupby, quant):
    if chart_type == 'Bubble Chart':
        return {
            "channels": {
                "x": None,
                "y": None,
                "color": groupby,
                "label": groupby,
                "size": quant
            },
            'geometry': 'circle'
        }
    else:
        return {
            "channels": {
                "x": groupby,
                "y": quant,
                "color": None,
                "label": None,
                "size": None
            },
            'geometry': 'rectangle'
        }
    
ls = hv.link_selections.instance()

geo = ls(windturbines.hvplot.points(
    'easting', 'northing', xaxis=None, yaxis=None, rasterize=True,
    tiles='CartoLight', responsive=True, dynspread=True,
    height=500, cnorm='log', cmap='plasma', xlim=(-14000000, -8000000),
    ylim=(3000000, 6500000)
))
    
groupby = pn.widgets.RadioButtonGroup(
    options={'State': 't_state', 'Year': 'p_year', 'Manufacturer': 't_manu'}, align='center'
)
chart_type = pn.widgets.RadioButtonGroup(
    options=['Bar Chart', 'Bubble Chart'], align='center'
)
quant = pn.widgets.RadioButtonGroup(
    options={'Count': 'Count', 'Capacity': 'p_cap'}, align='center'
)
lsdata = ls.selection_param(windturbines)

vizzu = pn.pane.Vizzu(
    pn.bind(data, lsdata, groupby, quant),
    config=pn.bind(config, chart_type, groupby, quant),
    column_types={'p_year': 'dimension'},
    style={
        "plot": {
            "xAxis": {
                "label": {
                    "angle": "-45deg"
                }
            }
        }
    },
    sizing_mode='stretch_both'
)

def format_df(df):
    df = df[['t_state', 't_county', 'p_name', 'p_year', 't_manu', 't_cap']]
    return df.rename(
        columns={col: col.split('_')[1].title() for col in df.columns}
    )


table = pn.widgets.Tabulator(
    pn.bind(format_df, lsdata), page_size=8, pagination='remote',
    show_index=False,
)

pn.Column(
    pn.Row(quant, "# by", groupby, "# as a", chart_type).servable(area='header'),
    pn.Column(
        pn.Row(geo, table),
        vizzu, min_height=1000,
        sizing_mode='stretch_both'
    ).servable(title='Windturbines')
)