Skip to article frontmatterSkip to article content

Visualization

import pandas as pd
import os
import holoviews as hv
import pickle
hv.extension('bokeh')
Loading...

Visualization

study_sites = pd.read_csv('study_sites.csv', index_col=0)
study_sites
Loading...
df = pd.read_csv('dataset.csv', parse_dates=True, index_col=0)

df.head(10)
Loading...
dictionary = {i: hv.Curve(df[str(i)], label=f"{study_sites.loc[i, 'waterbody']} - {study_sites.loc[i, 'station']} ({study_sites.loc[i, 'depth (m)']}m)")
                for i in study_sites.index }
hv.HoloMap(dictionary, kdims='Study Site').opts(aspect=2)
Loading...

Visualize results

import holoviews as hv
hv.extension('bokeh')

df = pd.read_csv('filtered_results.csv')

plots = []
for metric in ['MAE', 'RMSE']:
    
    scatter = hv.NdOverlay({
        imputer: hv.Scatter(df[df['imputer_name'] == imputer], 'missing_fraction', metric, label=imputer).opts(size=8)
        for imputer in df['imputer_name'].unique()
    })
    
    scatter.opts(
        title=f'{metric} vs Missing Fraction by Imputation Strategy',
        xlabel='Missing Fraction (%)',
        ylabel=metric,
        width=800,
        height=400,
        legend_position='right'
    )

    plots.append(scatter)

(plots[0] + plots[1]).cols(1)
Loading...
# Load results
results_dir = 'results'
data = []

for fname in os.listdir(results_dir):
    if fname.endswith('.pkl'):
        with open(os.path.join(results_dir, fname), 'rb') as f:
            result = pickle.load(f)
        
        data.append(result)
import holoviews as hv
import pandas as pd
from holoviews import opts

import param

hv.extension('bokeh')

# Convert your list of dictionaries into a DataFrame
df = pd.DataFrame(data)  # assuming 'data' is your list of result dicts

class Explorer(param.Parameterized):
    imputer = param.ObjectSelector(default=df['imputer_name'].unique()[0], objects=list(df['imputer_name'].unique()))
    metric = param.ObjectSelector(default='MAE', objects=['MAE', 'RMSE'])

    @param.depends('imputer', 'metric')
    def view(self):
        subset = df[df['imputer_name'] == self.imputer]
        return hv.Scatter(subset, 'missing_fraction', self.metric).opts(
            title=f'{self.metric} vs Missing Fraction ({self.imputer})',
            xlabel='Missing Fraction (%)',
            ylabel=self.metric,
            size=8,
            alpha=0.7,
            width=700,
            height=400
        )

explorer = Explorer()
hv.DynamicMap(explorer.view)
Loading...
import panel as pn
pn.extension()

import param
import holoviews as hv
hv.extension('bokeh')

class ResultsExplorer(param.Parameterized):
    imputer = param.ObjectSelector(default=df['imputer_name'].unique()[0],
                                    objects=list(df['imputer_name'].unique()))
    metric = param.ObjectSelector(default='MAE', objects=['MAE', 'RMSE'])

    @param.depends('imputer', 'metric')
    def view(self):
        subset = df[df['imputer_name'] == self.imputer]
        return hv.Scatter(subset, 'missing_fraction', self.metric).opts(
            title=f'{self.metric} vs Missing Fraction ({self.imputer})',
            xlabel='Missing Fraction (%)',
            ylabel=self.metric,
            size=8,
            alpha=0.7,
            width=800,
            height=400
        )

explorer = ResultsExplorer()
Loading...
# Create a Panel layout with separate controls and plot
controls = pn.Param(
    explorer.param,
    widgets={
        'imputer': pn.widgets.Select,
        'metric': pn.widgets.RadioButtonGroup
    },
    show_name=False
)

# Compose everything together in a clean layout
dashboard = pn.Row(
    pn.Column(pn.pane.Markdown("### Controls"), controls, width=250),
    pn.Column(explorer.view)
)

dashboard
Loading...
# Load your data dictionary
results_dir = 'results'
data = {}
for fname in os.listdir(results_dir):
    if fname.endswith('.pkl'):
        with open(os.path.join(results_dir, fname), 'rb') as f:
            data[fname] = pickle.load(f)

# Widgets
imputer_selector = param.ObjectSelector(default=df['imputer_name'].unique()[0], objects=list(df['imputer_name'].unique()))
experiment_selector = pn.widgets.Select(name='Experiment', options=list(data.keys()))
column_selector = pn.widgets.Select(name='Column', options=[])

# Update column options
def update_columns(event=None):
    df = data[experiment_selector.value]['df']
    column_selector.options = list(df.columns)

experiment_selector.param.watch(update_columns, 'value')
update_columns()

# Plot function
@pn.depends(experiment_selector, column_selector)
def overlay_plot(experiment, column):
    entry = data[experiment]
    curves = []
    labels = {'df': 'Observed', 'df_true': 'True', 'df_imputed': 'Imputed'}
    colors = {'df': 'gray', 'df_true': 'green', 'df_imputed': 'orange'}

    for key in ['df_true', 'df_imputed', 'df']:
        if key in entry and column in entry[key].columns:
            df = entry[key]
            curve = hv.Curve((df.index, df[column]), 'Time', 'Value', label=labels[key]).opts(color=colors[key])
            curves.append(curve)

    overlay = hv.Overlay(curves)

    # Add gap highlight from internal 'gaps' key
    if 'gaps' in entry and column in entry['gaps']:
        df = entry['df']
        start_idx, end_idx = entry['gaps'][column]
        x0 = df.index[start_idx]
        x1 = df.index[end_idx]
        y0 = df[column].min()
        y1 = df[column].max()
        gap_box = hv.Rectangles([(x0, y0, x1, y1)]).opts(
            fill_color='lightgray',
            fill_alpha=0.5,
            line_alpha=0,
            tools=[]
        )
        overlay *= gap_box

    return overlay.opts(
        title=f"{column} across Observed, True, and Imputed",
        width=800,
        height=400,
        legend_position='right',
        tools=['hover']
    )
# Layout
dashboard = pn.Column(
    pn.Row(experiment_selector, column_selector),
    overlay_plot
)

dashboard.servable()
Loading...