
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
############ Imports ##############
import vizro.plotly.express as px
import vizro.models as vm
from vizro import Vizro
import pandas as pd
from vizro.managers import data_manager
from vizro.tables import dash_ag_grid
####### Data Manager Settings #####
data_manager["electricity_data"] = pd.read_csv(
"https://ourworldindata.org/grapher/share-of-the-population-with-access-to-electricity.csv",
).sort_values("Year") # NEW: needed so that the animation on the choropleth map works in the right order
########### Model code ############
model = vm.Dashboard(
pages=[
vm.Page(
title="Share of the population with access to electricity",
components=[
vm.Tabs(
tabs=[
# NEW: a table here is very easy to do. LLM should be able to do this.
vm.Container(title="Table", components=[vm.AgGrid(figure=dash_ag_grid("electricity_data"))]),
vm.Container(
title="Map",
components=[
vm.Graph(
id="electricity_map",
figure=(
px.choropleth(
data_frame="electricity_data",
locations="Code",
color="Access to electricity (% of population)",
hover_name="Entity",
hover_data={
"Access to electricity (% of population)": ":.1f%",
"Code": False,
"Year": False,
},
animation_frame="Year", # NEW: animation_frame and animation_group. LLM should be able to do this.
animation_group="Entity",
labels={
"Access to electricity (% of population)": "Access to Electricity (%)"
},
range_color=[0, 100],
# REMOVED: `color_continuous_scale` not necessary but basically harmless
# REMOVED: height=600 probably harmful and best to avoid
)
),
)
],
controls=[
# NEW: you actually can change the projection to a 3D one
# See https://py.cafe/antonymilne/plotly-map-projections for all examples.
# LLM should be able to do this.
vm.Parameter(
targets=["electricity_map.projection"],
selector=vm.RadioItems(options=["natural earth", "orthographic"]),
)
],
),
vm.Container(
title="Line",
components=[
vm.Graph(
id="electricity_line",
figure=(
px.line(
data_frame="electricity_data",
x="Year",
y="Access to electricity (% of population)",
color="Entity",
range_y=[0, 100], # NEW: fix the range (matter of taste really, it's ok without). LLM should be able to do this.
)
),
)
],
),
vm.Container(
title="Bar",
components=[
vm.Graph(
id="electricity_bar",
figure=(
px.bar(
data_frame="electricity_data",
x="Access to electricity (% of population)",
y="Entity",
color="Entity",
text_auto=".1f", # NEW: to annotate the bars (not important). LLM should be able to do this.
# REMOVED: orientation="h" not necessary but harmless.
)
),
)
],
controls=[
vm.Filter(
column="Year",
selector=vm.Slider(
id="year_slider",
step=1,
value=2023,
marks={year: str(year) for year in range(1990, 2024, 5)},
),
)
],
),
]
)
],
controls=[
vm.Filter(
column="Entity",
selector=vm.Dropdown(
value=[
"United States",
"China",
"Brazil",
"India",
"Afghanistan",
"Rwanda",
"Haiti",
],
extra={"optionHeight": 35},
# REMOVED: multi=False is the default so unnecessary but harmless.
),
targets=["electricity_bar", "electricity_line"],
)
],
)
]
)
# CHANGES throughout:
# - removed titles where I thought they weren't necessary
# - different structure that actually uses Tabs. Take note of where controls are and what they apply to: Entity filter at page-level apply to both graphs; slider next to bar chart applies to just that chart.
# LLM should be able to get this all right.
# NEW:
# - assets/custom.css file to make range slider a nice width. Not essential but nice to have, LLM should be able to do it but might get confused. You need to give vm.Slider an `id` for that to work.
app = Vizro().build(model)
if __name__ == "__main__":
app.run(debug=True, port=8050)