chrisli124 commited on
Commit
232e1d8
Β·
verified Β·
1 Parent(s): ffb1692

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +96 -160
app.py CHANGED
@@ -1,162 +1,98 @@
1
- import faicons as fa
 
 
 
 
2
  import plotly.express as px
3
-
4
- # Load data and compute static values
5
- from shared import app_dir, tips
6
- from shinywidgets import render_plotly
7
-
8
- from shiny import reactive, render
9
- from shiny.express import input, ui
10
-
11
- bill_rng = (min(tips.total_bill), max(tips.total_bill))
12
-
13
- # Add page title and sidebar
14
- ui.page_opts(title="Restaurant tipping", fillable=True)
15
-
16
- with ui.sidebar(open="desktop"):
17
- ui.input_slider(
18
- "total_bill",
19
- "Bill amount",
20
- min=bill_rng[0],
21
- max=bill_rng[1],
22
- value=bill_rng,
23
- pre="$",
24
- )
25
- ui.input_checkbox_group(
26
- "time",
27
- "Food service",
28
- ["Lunch", "Dinner"],
29
- selected=["Lunch", "Dinner"],
30
- inline=True,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  )
32
- ui.input_action_button("reset", "Reset filter")
33
-
34
- # Add main content
35
- ICONS = {
36
- "user": fa.icon_svg("user", "regular"),
37
- "wallet": fa.icon_svg("wallet"),
38
- "currency-dollar": fa.icon_svg("dollar-sign"),
39
- "ellipsis": fa.icon_svg("ellipsis"),
40
- }
41
-
42
- with ui.layout_columns(fill=False):
43
- with ui.value_box(showcase=ICONS["user"]):
44
- "Total tippers"
45
-
46
- @render.express
47
- def total_tippers():
48
- tips_data().shape[0]
49
-
50
- with ui.value_box(showcase=ICONS["wallet"]):
51
- "Average tip"
52
-
53
- @render.express
54
- def average_tip():
55
- d = tips_data()
56
- if d.shape[0] > 0:
57
- perc = d.tip / d.total_bill
58
- f"{perc.mean():.1%}"
59
-
60
- with ui.value_box(showcase=ICONS["currency-dollar"]):
61
- "Average bill"
62
-
63
- @render.express
64
- def average_bill():
65
- d = tips_data()
66
- if d.shape[0] > 0:
67
- bill = d.total_bill.mean()
68
- f"${bill:.2f}"
69
-
70
-
71
- with ui.layout_columns(col_widths=[6, 6, 12]):
72
- with ui.card(full_screen=True):
73
- ui.card_header("Tips data")
74
-
75
- @render.data_frame
76
- def table():
77
- return render.DataGrid(tips_data())
78
-
79
- with ui.card(full_screen=True):
80
- with ui.card_header(class_="d-flex justify-content-between align-items-center"):
81
- "Total bill vs tip"
82
- with ui.popover(title="Add a color variable", placement="top"):
83
- ICONS["ellipsis"]
84
- ui.input_radio_buttons(
85
- "scatter_color",
86
- None,
87
- ["none", "sex", "smoker", "day", "time"],
88
- inline=True,
89
- )
90
-
91
- @render_plotly
92
- def scatterplot():
93
- color = input.scatter_color()
94
- return px.scatter(
95
- tips_data(),
96
- x="total_bill",
97
- y="tip",
98
- color=None if color == "none" else color,
99
- trendline="lowess",
100
- )
101
-
102
- with ui.card(full_screen=True):
103
- with ui.card_header(class_="d-flex justify-content-between align-items-center"):
104
- "Tip percentages"
105
- with ui.popover(title="Add a color variable"):
106
- ICONS["ellipsis"]
107
- ui.input_radio_buttons(
108
- "tip_perc_y",
109
- "Split by:",
110
- ["sex", "smoker", "day", "time"],
111
- selected="day",
112
- inline=True,
113
- )
114
-
115
- @render_plotly
116
- def tip_perc():
117
- from ridgeplot import ridgeplot
118
-
119
- dat = tips_data()
120
- dat["percent"] = dat.tip / dat.total_bill
121
- yvar = input.tip_perc_y()
122
- uvals = dat[yvar].unique()
123
-
124
- samples = [[dat.percent[dat[yvar] == val]] for val in uvals]
125
-
126
- plt = ridgeplot(
127
- samples=samples,
128
- labels=uvals,
129
- bandwidth=0.01,
130
- colorscale="viridis",
131
- colormode="row-index",
132
- )
133
-
134
- plt.update_layout(
135
- legend=dict(
136
- orientation="h", yanchor="bottom", y=1.02, xanchor="center", x=0.5
137
- )
138
- )
139
-
140
- return plt
141
-
142
-
143
- ui.include_css(app_dir / "styles.css")
144
-
145
- # --------------------------------------------------------
146
- # Reactive calculations and effects
147
- # --------------------------------------------------------
148
-
149
-
150
- @reactive.calc
151
- def tips_data():
152
- bill = input.total_bill()
153
- idx1 = tips.total_bill.between(bill[0], bill[1])
154
- idx2 = tips.time.isin(input.time())
155
- return tips[idx1 & idx2]
156
-
157
-
158
- @reactive.effect
159
- @reactive.event(input.reset)
160
- def _():
161
- ui.update_slider("total_bill", value=bill_rng)
162
- ui.update_checkbox_group("time", selected=["Lunch", "Dinner"])
 
1
+ from shiny import App, ui, render, reactive
2
+ from shinywidgets import render_widget
3
+ from ipyleaflet import Map, TileLayer, GeoJSON, LayersControl
4
+ import pandas as pd
5
+ import numpy as np
6
  import plotly.express as px
7
+ import plotly.graph_objects as go
8
+ from plotly.subplots import make_subplots
9
+ import matplotlib.pyplot as plt
10
+ from ipywidgets import Output
11
+ import rasterio
12
+ import json
13
+
14
+ # ---- 1. Load Data ----
15
+ # Example file paths (replace with actual paths or S3 calls)
16
+ wealth_tif_path = "data/wealth_map.tif"
17
+ improvement_csv_path = "data/poverty_improvement_by_state.csv"
18
+
19
+ # Read CSV
20
+ improvement_data = pd.read_csv(improvement_csv_path)
21
+
22
+ # Load raster stack
23
+ wealth_stack = rasterio.open(wealth_tif_path)
24
+
25
+ # Time periods corresponding to bands
26
+ time_periods = [
27
+ "1990–1992", "1993–1995", "1996–1998", "1999–2001", "2002–2004",
28
+ "2005–2007", "2008–2010", "2011–2013", "2014–2016", "2017–2019"
29
+ ]
30
+
31
+ # ---- 2. UI ----
32
+ app_ui = ui.page_fluid(
33
+ ui.h2("Africa Wealth Map Dashboard (Python Version)"),
34
+ ui.layout_sidebar(
35
+ ui.panel_sidebar(
36
+ ui.input_slider("time_index", "Select Time Period (Years):", 1, 10, 1),
37
+ ui.input_select("color_palette", "Select Color Palette:", {
38
+ "viridis": "Viridis", "plasma": "Plasma", "magma": "Magma",
39
+ "inferno": "Inferno", "Spectral": "Spectral (Brewer)"
40
+ }),
41
+ ui.input_slider("opacity", "Map Opacity:", 0.2, 1.0, 0.8, step=0.1)
42
+ ),
43
+ ui.panel_main(
44
+ ui.output_text("current_year_range"),
45
+ ui.output_plot("iwi_histogram"),
46
+ ui.output_plot("trend_plot"),
47
+ ui.output_plot("clicked_ts_plot")
48
+ )
49
  )
50
+ )
51
+
52
+ # ---- 3. Server ----
53
+ def server(input, output, session):
54
+
55
+ selected_band = reactive.Calc(lambda: input.time_index())
56
+
57
+ @output
58
+ @render.text
59
+ def current_year_range():
60
+ return time_periods[input.time_index() - 1]
61
+
62
+ @output
63
+ @render.plot
64
+ def iwi_histogram():
65
+ band_index = input.time_index() - 1
66
+ band_data = wealth_stack.read(band_index + 1).flatten()
67
+ band_data = band_data[(band_data > 0) & (band_data <= 1)]
68
+ plt.figure(figsize=(6, 4))
69
+ plt.hist(band_data, bins=20, color="skyblue", edgecolor="white")
70
+ plt.title("IWI Histogram")
71
+ plt.xlabel("IWI")
72
+ plt.ylabel("Frequency")
73
+ return plt.gcf()
74
+
75
+ @output
76
+ @render.plot
77
+ def trend_plot():
78
+ mean_iwi = []
79
+ for i in range(1, 11):
80
+ band_data = wealth_stack.read(i).flatten()
81
+ band_data = band_data[(band_data > 0) & (band_data <= 1)]
82
+ mean_iwi.append(np.mean(band_data))
83
+
84
+ fig = go.Figure()
85
+ fig.add_trace(go.Scatter(x=time_periods, y=mean_iwi, mode='lines+markers'))
86
+ fig.update_layout(title="Average IWI Over Time", xaxis_title="Period", yaxis_title="Mean IWI")
87
+ return fig
88
+
89
+ @output
90
+ @render.plot
91
+ def clicked_ts_plot():
92
+ # Placeholder until integrated with map click logic
93
+ fig = go.Figure()
94
+ fig.update_layout(title="Click on map to load time series")
95
+ return fig
96
+
97
+ # ---- 4. App ----
98
+ app = App(app_ui, server)