Skip to content

Instantly share code, notes, and snippets.

@andrie
Created August 22, 2023 10:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andrie/595d9b439d7c29eac2c1c1bb963d8e7f to your computer and use it in GitHub Desktop.
Save andrie/595d9b439d7c29eac2c1c1bb963d8e7f to your computer and use it in GitHub Desktop.
Shiny for python app that filters data prior to display in grid.
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