Created
August 22, 2023 10:51
-
-
Save andrie/595d9b439d7c29eac2c1c1bb963d8e7f to your computer and use it in GitHub Desktop.
Shiny for python app that filters data prior to display in grid.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pandas # noqa: F401 (this line needed for Shinylive to load plotly.express) | |
import plotly.express as px | |
import plotly.graph_objs as go | |
from shinywidgets import output_widget, render_widget | |
from shiny import App | |
from shiny import experimental as x | |
from shiny import reactive, render, req, session, ui | |
# Load the Gapminder dataset | |
df = px.data.gapminder() | |
# breakpoint() | |
# Prepare a summary DataFrame | |
summary_df = ( | |
df.groupby("country") | |
.agg( | |
{ | |
"pop": ["min", "max", "mean"], | |
"lifeExp": ["min", "max", "mean"], | |
"gdpPercap": ["min", "max", "mean"], | |
} | |
) | |
.reset_index() | |
) | |
summary_df.columns = ["_".join(col).strip() for col in summary_df.columns.values] | |
summary_df.rename(columns={"country_": "country"}, inplace=True) | |
app_ui = x.ui.page_fillable( | |
{"class": "p-3"}, | |
ui.p( | |
ui.strong("Instructions:"), | |
" Select a country in the table below to see more information.", | |
), | |
x.ui.layout_column_wrap( | |
1, | |
x.ui.layout_column_wrap( | |
1/2, | |
x.ui.card( | |
ui.input_text("country_filter", "Filter by Country"), #, value="aus"), | |
max_height = "7em", | |
), | |
x.ui.card( | |
ui.p("Selected country"), | |
ui.output_text("selected_country_text"), | |
max_height = "7em", | |
), | |
max_height="0", | |
), | |
x.ui.card( | |
ui.output_data_frame("summary_data"), | |
), | |
x.ui.layout_column_wrap( | |
1, | |
x.ui.card( | |
ui.output_data_frame("filtered_df_table"), | |
), | |
), | |
heights_equal="row", | |
), | |
) | |
def server(input, output, session): | |
@reactive.Calc | |
def pre_filter_data(): | |
f = input.country_filter().lower() | |
dat = summary_df | |
if f != "": | |
# it's important to reset the index after filtering!!! | |
dat = dat[dat.country.str.lower().str.contains(f)].reset_index() | |
return dat | |
@output | |
@render.data_frame | |
def summary_data(): | |
return render.DataGrid( | |
pre_filter_data().round(2), | |
row_selection_mode="single", | |
width="100%", | |
height="100%", | |
) | |
@reactive.Calc | |
def selected_country(): | |
req(len(input.summary_data_selected_rows()) > 0) | |
selected_idx = input.summary_data_selected_rows()[0] | |
countries = pre_filter_data()["country"][selected_idx] | |
return countries | |
@output | |
@render.text | |
def selected_country_text(): | |
return selected_country() | |
@reactive.Calc | |
def filtered_df(): | |
countries = selected_country() | |
return df[df["country"] == selected_country()] | |
@output | |
@render.data_frame | |
def filtered_df_table(): | |
return render.DataGrid( | |
filtered_df(), | |
width="100%", | |
height="100%", | |
) | |
app = App(app_ui, server) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment