Skip to content

Commit 90ed9c8

Browse files
cgraham-rsdotNomad
andauthored
Add top-5-income-share-shiny (#106)
* Add top-5-income-share-shiny * Use example category --------- Co-authored-by: Jordan Jensen <[email protected]>
1 parent 3482058 commit 90ed9c8

File tree

6 files changed

+969
-0
lines changed

6 files changed

+969
-0
lines changed

.github/workflows/extensions.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ jobs:
3434
quarto-stock-report-python: extensions/quarto-stock-report-python/**
3535
quarto-website: extensions/quarto-website/**
3636
portfolio-dashboard: extensions/portfolio-dashboard/**
37+
top-5-income-share-shiny: extensions/top-5-income-share-shiny/**
3738
quarto-document: extensions/quarto-document/**
3839
stock-api-plumber: extensions/stock-api-plumber/**
3940
stock-api-flask: extensions/stock-api-flask/**
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Top 5% income share
2+
3+
## About this example
4+
5+
A Shiny application makes it easy to transform your analysis into an interactive application using Python so users can ask and answer their own questions in real-time.
6+
7+
8+
## Learn more
9+
10+
* [Shiny for Python documentation](https://shiny.posit.co/py/)
11+
* [Shiny for Python examples](https://shinylive.io/py/examples/)
12+
13+
## Requirements
14+
15+
* Python version 3.9 or higher
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import altair as alt
2+
import pandas as pd
3+
from shinywidgets import output_widget, render_widget
4+
from shiny import App, reactive, ui
5+
6+
income_shares = pd.read_csv("data.csv")
7+
countries = income_shares["Entity"].unique().tolist()
8+
9+
select_countries = {
10+
"default": ["Australia", "China", "Germany", "Japan", "United States"],
11+
"latam": ["Argentina", "Uruguay"],
12+
"apac": ["Australia", "China", "Singapore", "Japan", "Korea, South"],
13+
"emea": ["Mauritius", "France", "Italy", "Norway", "Spain"],
14+
"na": ["United States", "Canada"],
15+
}
16+
17+
app_ui = ui.page_fluid(
18+
ui.panel_title("Top 5% Income Share"),
19+
ui.p("Share of income received by the richest 5% of the population"),
20+
ui.layout_sidebar(
21+
ui.sidebar(
22+
ui.input_selectize(
23+
"countries",
24+
"Countries:",
25+
choices=countries,
26+
multiple=True,
27+
selected=select_countries["default"],
28+
),
29+
ui.p("Regions:"),
30+
ui.TagList(
31+
ui.div(
32+
{"class": "btn-group"},
33+
ui.input_action_button("apac", "APAC"),
34+
ui.input_action_button("emea", "EMEA"),
35+
ui.input_action_button("latam", "LATAM"),
36+
ui.input_action_button("na", "NA"),
37+
)
38+
),
39+
ui.input_slider(
40+
"year_range",
41+
"Year Range:",
42+
min=1946,
43+
max=2015,
44+
value=(1946, 2015),
45+
sep="",
46+
),
47+
),
48+
output_widget("income_plot", width="800px"),
49+
),
50+
)
51+
52+
53+
def server(input, output, session):
54+
@reactive.Calc
55+
def plot_data():
56+
df = income_shares.loc[
57+
(income_shares["Entity"].isin(input.countries()))
58+
& (income_shares["Year"] >= input.year_range()[0])
59+
& (income_shares["Year"] <= input.year_range()[1])
60+
]
61+
return df
62+
63+
@output
64+
@render_widget
65+
def income_plot():
66+
chart = (
67+
alt.Chart(plot_data())
68+
.mark_line()
69+
.encode(
70+
x=alt.X("Year", axis=alt.Axis(format="d")),
71+
y=alt.Y("Percent", axis=alt.Axis(format="~s")),
72+
color="Entity",
73+
strokeDash="Entity",
74+
)
75+
)
76+
return chart
77+
78+
def make_button_listener(name):
79+
@reactive.Effect
80+
@reactive.event(input[name])
81+
def _():
82+
ui.update_selectize("countries", selected=select_countries[name])
83+
84+
for name in select_countries.keys():
85+
make_button_listener(name)
86+
87+
88+
app = App(app_ui, server)
89+
if __name__ == "__main__":
90+
app.run()

0 commit comments

Comments
 (0)