Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
# app.py — Titanic Data Adventure (
|
| 2 |
|
| 3 |
import gradio as gr
|
| 4 |
import pandas as pd
|
|
@@ -117,23 +117,23 @@ def train_and_embed_solid():
|
|
| 117 |
return status, fig
|
| 118 |
|
| 119 |
# ======================================================
|
| 120 |
-
#
|
| 121 |
# ======================================================
|
| 122 |
INTRO_MD = """
|
| 123 |
<span style='color:#1B4B91'>
|
| 124 |
-
April 1912
|
| 125 |
-
De RMS Titanic vertrekt richting New York: een drijvend paleis, gevuld met verwachtingen
|
| 126 |
-
Aan boord: industriëlen in avondkleding, jonge gezinnen met één koffer, bemanningsleden met routine
|
| 127 |
-
De zee is kalm; de toekomst lijkt maakbaar. Meer dan een eeuw later kijken wij mee — niet met verrekijkers of logboeken, maar met data
|
| 128 |
-
Elk record in deze dataset is een menselijk verhaal: iemand met een plek aan tafel, een ticket, een familie, een keuze
|
| 129 |
Door de gegevens te verkennen, begrijpen we beter wie overleefde — en waarom.
|
| 130 |
</span>
|
| 131 |
"""
|
| 132 |
|
| 133 |
EXPLAIN_MD_SIDE = """
|
| 134 |
<span style='color:#1B4B91'>
|
| 135 |
-
Bij het opstarten traint de computer een RandomForest-model dat leert wie op de Titanic overleefde – en waarom
|
| 136 |
-
Het kijkt naar klasse, geslacht, leeftijd, familieomvang, ticketprijs en haven van vertrek
|
| 137 |
De nauwkeurigheid (bijv. 74%) betekent: in 74 van de 100 gevallen voorspelt het model correct.
|
| 138 |
</span>
|
| 139 |
"""
|
|
@@ -156,6 +156,78 @@ def plot_fare_box(dfx):
|
|
| 156 |
color_discrete_map={"Overleefd":"#1B4B91","Niet overleefd":"#A3B1C6"})
|
| 157 |
return make_plot(f, "Ticketprijs per klasse (met overleving)")
|
| 158 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 159 |
# ======================================================
|
| 160 |
# UI + LAYOUT
|
| 161 |
# ======================================================
|
|
@@ -165,21 +237,41 @@ body { background:#FFFFFF; color:#0B1C3F; }
|
|
| 165 |
h1, h2, h3, h4 { color:#1B4B91; }
|
| 166 |
.panel, .intro-card { background:#F9FBFF; border:1px solid #E0E6F3; border-radius:12px; padding:16px; }
|
| 167 |
.hero-img img { border-radius:12px; border:1px solid #E0E6F3; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 168 |
"""
|
| 169 |
|
| 170 |
with gr.Blocks(css=CUSTOM_CSS, theme=gr.themes.Default(primary_hue="blue")) as demo:
|
|
|
|
| 171 |
with gr.Row():
|
| 172 |
with gr.Column(scale=2, min_width=420):
|
| 173 |
-
|
|
|
|
| 174 |
with gr.Column(scale=1, min_width=320):
|
| 175 |
hp = hero_path()
|
| 176 |
-
if hp:
|
| 177 |
gr.Image(value=hp, interactive=False, show_label=False, elem_classes=["hero-img"])
|
| 178 |
-
else:
|
| 179 |
gr.Markdown("⚠️ **Geen afbeelding gevonden.** Plaats `titanic_bg.png` of `titanic_bg.jpg` in de root.")
|
| 180 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 181 |
gr.Markdown("")
|
| 182 |
|
|
|
|
| 183 |
with gr.Column(elem_classes=["panel"]):
|
| 184 |
gr.Markdown("## 🔧 Initialisatie & Modeltraining")
|
| 185 |
status_md = gr.Markdown("⏳ Initialiseren…")
|
|
@@ -187,13 +279,17 @@ with gr.Blocks(css=CUSTOM_CSS, theme=gr.themes.Default(primary_hue="blue")) as d
|
|
| 187 |
with gr.Column(scale=2, min_width=420):
|
| 188 |
train_plot = gr.Plot(label="2D-projectie — elk bolletje is een passagier")
|
| 189 |
with gr.Column(scale=1, min_width=320):
|
| 190 |
-
|
|
|
|
| 191 |
|
|
|
|
| 192 |
with gr.Row():
|
| 193 |
-
gr.HTML(f"<div
|
| 194 |
-
gr.HTML(f"<div
|
| 195 |
-
gr.HTML(f"<div
|
|
|
|
| 196 |
|
|
|
|
| 197 |
gr.Markdown("## 📊 Verken de data", elem_classes=["panel"])
|
| 198 |
with gr.Row():
|
| 199 |
g2 = gr.Plot(label="Leeftijdsverdeling per status")
|
|
@@ -201,7 +297,61 @@ with gr.Blocks(css=CUSTOM_CSS, theme=gr.themes.Default(primary_hue="blue")) as d
|
|
| 201 |
with gr.Row():
|
| 202 |
g4 = gr.Plot(label="Ticketprijs per klasse")
|
| 203 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 204 |
demo.load(fn=train_and_embed_solid, inputs=[], outputs=[status_md, train_plot])
|
| 205 |
demo.load(lambda: (plot_age_hist(df), plot_gender(df), plot_fare_box(df)), inputs=[], outputs=[g2, g3, g4])
|
| 206 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 207 |
demo.launch()
|
|
|
|
| 1 |
+
# app.py — Titanic Data Adventure (met uitgebreide introductie naast foto)
|
| 2 |
|
| 3 |
import gradio as gr
|
| 4 |
import pandas as pd
|
|
|
|
| 117 |
return status, fig
|
| 118 |
|
| 119 |
# ======================================================
|
| 120 |
+
# TEKSTBLOKKEN — ALLEEN BLAUW, GEEN ZWART/GEEN VET
|
| 121 |
# ======================================================
|
| 122 |
INTRO_MD = """
|
| 123 |
<span style='color:#1B4B91'>
|
| 124 |
+
April 1912.<br>
|
| 125 |
+
De RMS Titanic vertrekt richting New York: een drijvend paleis, gevuld met verwachtingen.<br>
|
| 126 |
+
Aan boord: industriëlen in avondkleding, jonge gezinnen met één koffer, bemanningsleden met routine.<br>
|
| 127 |
+
De zee is kalm; de toekomst lijkt maakbaar. Meer dan een eeuw later kijken wij mee — niet met verrekijkers of logboeken, maar met data.<br>
|
| 128 |
+
Elk record in deze dataset is een menselijk verhaal: iemand met een plek aan tafel, een ticket, een familie, een keuze.<br>
|
| 129 |
Door de gegevens te verkennen, begrijpen we beter wie overleefde — en waarom.
|
| 130 |
</span>
|
| 131 |
"""
|
| 132 |
|
| 133 |
EXPLAIN_MD_SIDE = """
|
| 134 |
<span style='color:#1B4B91'>
|
| 135 |
+
Bij het opstarten traint de computer een RandomForest-model dat leert wie op de Titanic overleefde – en waarom.<br>
|
| 136 |
+
Het kijkt naar klasse, geslacht, leeftijd, familieomvang, ticketprijs en haven van vertrek.<br>
|
| 137 |
De nauwkeurigheid (bijv. 74%) betekent: in 74 van de 100 gevallen voorspelt het model correct.
|
| 138 |
</span>
|
| 139 |
"""
|
|
|
|
| 156 |
color_discrete_map={"Overleefd":"#1B4B91","Niet overleefd":"#A3B1C6"})
|
| 157 |
return make_plot(f, "Ticketprijs per klasse (met overleving)")
|
| 158 |
|
| 159 |
+
# ======================================================
|
| 160 |
+
# INTERACTIEVE VOORSPELLING
|
| 161 |
+
# ======================================================
|
| 162 |
+
def predict_and_story(pclass, sex, age, sibsp, parch, fare, embarked):
|
| 163 |
+
if MODEL is None:
|
| 164 |
+
return "⏳ Het model initialiseert nog. Probeer het zo nog eens."
|
| 165 |
+
X_row = pd.DataFrame([{
|
| 166 |
+
"pclass": int(pclass), "sex": sex, "age": float(age),
|
| 167 |
+
"sibsp": int(sibsp), "parch": int(parch), "fare": float(fare),
|
| 168 |
+
"embarked": embarked, "family_size": int(sibsp)+int(parch)+1
|
| 169 |
+
}])
|
| 170 |
+
prob = float(MODEL.predict_proba(X_row)[0,1]); pct = prob*100
|
| 171 |
+
klasse_txt = {1:"eerste",2:"tweede",3:"derde"}[int(pclass)]
|
| 172 |
+
haven_txt = {"C":"Cherbourg","Q":"Queenstown","S":"Southampton"}[embarked]
|
| 173 |
+
rol_txt = "vrouw" if sex.lower().startswith("v") else "man"
|
| 174 |
+
if pct>=75:
|
| 175 |
+
tone, ending = ("Je kansen zijn uitzonderlijk goed.",
|
| 176 |
+
"Je bereikt de sloep; het schip helt achter je, maar je leeft.")
|
| 177 |
+
elif pct>=50:
|
| 178 |
+
tone, ending = ("Je kansen zijn behoorlijk goed.",
|
| 179 |
+
"In de chaos vind je een plek in een halfgevulde sloep.")
|
| 180 |
+
elif pct>=25:
|
| 181 |
+
tone, ending = ("De kansen zijn fifty-fifty.",
|
| 182 |
+
"Op het laatste moment spring je; de nacht is lang, maar de horizon gloeit.")
|
| 183 |
+
else:
|
| 184 |
+
tone, ending = ("Het ziet er somber uit.",
|
| 185 |
+
"Je klampt je vast terwijl de oceaan meedogenloos wordt.")
|
| 186 |
+
return f"""### 🔮 Jouw overlevingskans: **{pct:.1f}%**
|
| 187 |
+
**Situatie:** {rol_txt}, **{klasse_txt} klasse**, inscheping **{haven_txt}** — leeftijd **{int(age)}**, familie **{int(sibsp)}+{int(parch)}** (totaal {int(sibsp)+int(parch)+1}), ticket **£{float(fare):.2f}**.
|
| 188 |
+
**Analyse:** {tone} Het model weegt o.a. klasse, geslacht, leeftijd en familieomvang mee.
|
| 189 |
+
**Avontuur:** De nacht is stil; fluiten, geroep, voetstappen. {ending}
|
| 190 |
+
"""
|
| 191 |
+
|
| 192 |
+
# ======================================================
|
| 193 |
+
# LIVE GAUGE VOOR JOUW SCENARIO (met kleurbanden + threshold)
|
| 194 |
+
# ======================================================
|
| 195 |
+
def live_viz(pclass, sex, age, sibsp, parch, fare, embarked):
|
| 196 |
+
# Retourneer een gauge die live de kans toont (0–100%) met kleurbanden
|
| 197 |
+
if MODEL is None:
|
| 198 |
+
return make_plot(go.Figure(), "Jouw overlevingskans (live)")
|
| 199 |
+
X_row = pd.DataFrame([{
|
| 200 |
+
"pclass": int(pclass), "sex": sex, "age": float(age),
|
| 201 |
+
"sibsp": int(sibsp), "parch": int(parch), "fare": float(fare),
|
| 202 |
+
"embarked": embarked, "family_size": int(sibsp)+int(parch)+1
|
| 203 |
+
}])
|
| 204 |
+
prob = float(MODEL.predict_proba(X_row)[0,1]) * 100.0
|
| 205 |
+
|
| 206 |
+
fig = go.Figure(go.Indicator(
|
| 207 |
+
mode="gauge+number",
|
| 208 |
+
value=prob,
|
| 209 |
+
number={"suffix": "%", "valueformat": ".1f"},
|
| 210 |
+
gauge={
|
| 211 |
+
"axis": {"range": [0, 100]},
|
| 212 |
+
"bar": {"thickness": 0.25},
|
| 213 |
+
# Kleurbanden (0–25 rood, 25–50 oranje, 50–75 geel, 75–100 groen)
|
| 214 |
+
"steps": [
|
| 215 |
+
{"range": [0, 25], "color": "#FDECEC"},
|
| 216 |
+
{"range": [25, 50], "color": "#FFF2E0"},
|
| 217 |
+
{"range": [50, 75], "color": "#FFF9D6"},
|
| 218 |
+
{"range": [75, 100], "color": "#E8F6EA"},
|
| 219 |
+
],
|
| 220 |
+
# Threshold-lijn op actuele waarde
|
| 221 |
+
"threshold": {
|
| 222 |
+
"line": {"color": "#1B4B91", "width": 4},
|
| 223 |
+
"thickness": 0.9,
|
| 224 |
+
"value": prob
|
| 225 |
+
},
|
| 226 |
+
},
|
| 227 |
+
title={"text": "Jouw overlevingskans (live)"}
|
| 228 |
+
))
|
| 229 |
+
return make_plot(fig, "Jouw overlevingskans (live)")
|
| 230 |
+
|
| 231 |
# ======================================================
|
| 232 |
# UI + LAYOUT
|
| 233 |
# ======================================================
|
|
|
|
| 237 |
h1, h2, h3, h4 { color:#1B4B91; }
|
| 238 |
.panel, .intro-card { background:#F9FBFF; border:1px solid #E0E6F3; border-radius:12px; padding:16px; }
|
| 239 |
.hero-img img { border-radius:12px; border:1px solid #E0E6F3; }
|
| 240 |
+
.kpi { display:flex; flex-direction:column; align-items:center; justify-content:center;
|
| 241 |
+
background:#FFFFFF; border:1px solid #E0E6F3; border-radius:12px; padding:14px; }
|
| 242 |
+
.kpi .value { font-size:1.6rem; font-weight:800; color:#1B4B91; }
|
| 243 |
+
.kpi .label { font-size:.9rem; color:#3F557A; }
|
| 244 |
+
.explain-card { background:#EAF0FF; border-radius:12px; padding:18px; border:1px solid #D5E0FA; }
|
| 245 |
"""
|
| 246 |
|
| 247 |
with gr.Blocks(css=CUSTOM_CSS, theme=gr.themes.Default(primary_hue="blue")) as demo:
|
| 248 |
+
# Header-intro + foto
|
| 249 |
with gr.Row():
|
| 250 |
with gr.Column(scale=2, min_width=420):
|
| 251 |
+
# Alleen blauwe tekst (HTML inline), geen vet/zwart
|
| 252 |
+
gr.Markdown(INTRO_MD, elem_classes=["intro-card"])
|
| 253 |
with gr.Column(scale=1, min_width=320):
|
| 254 |
hp = hero_path()
|
| 255 |
+
if hp:
|
| 256 |
gr.Image(value=hp, interactive=False, show_label=False, elem_classes=["hero-img"])
|
| 257 |
+
else:
|
| 258 |
gr.Markdown("⚠️ **Geen afbeelding gevonden.** Plaats `titanic_bg.png` of `titanic_bg.jpg` in de root.")
|
| 259 |
|
| 260 |
+
# Passagierslijst — volledige dataset, scrollbaar
|
| 261 |
+
with gr.Column(elem_classes=["panel"]):
|
| 262 |
+
gr.Markdown("## 👥 Passagierslijst — volledige dataset (scrollbaar)")
|
| 263 |
+
gr.DataFrame(
|
| 264 |
+
value=df, # volledige dataset
|
| 265 |
+
wrap=True,
|
| 266 |
+
interactive=False, # alleen-lezen
|
| 267 |
+
label="Titanic-passagiers",
|
| 268 |
+
max_height=320 # vaste hoogte -> scroll binnen de tabel
|
| 269 |
+
)
|
| 270 |
+
|
| 271 |
+
# Spacer om overlap te voorkomen
|
| 272 |
gr.Markdown("")
|
| 273 |
|
| 274 |
+
# Panel: status + 2D-plot links en uitleg rechts
|
| 275 |
with gr.Column(elem_classes=["panel"]):
|
| 276 |
gr.Markdown("## 🔧 Initialisatie & Modeltraining")
|
| 277 |
status_md = gr.Markdown("⏳ Initialiseren…")
|
|
|
|
| 279 |
with gr.Column(scale=2, min_width=420):
|
| 280 |
train_plot = gr.Plot(label="2D-projectie — elk bolletje is een passagier")
|
| 281 |
with gr.Column(scale=1, min_width=320):
|
| 282 |
+
# Alleen blauwe tekst (HTML inline), geen vet/zwart
|
| 283 |
+
gr.Markdown(EXPLAIN_MD_SIDE, elem_classes=["explain-card"])
|
| 284 |
|
| 285 |
+
# KPIs
|
| 286 |
with gr.Row():
|
| 287 |
+
gr.HTML(f"<div class='kpi'><div class='value'>{len(df):,}</div><div class='label'>Totaal passagiers</div></div>")
|
| 288 |
+
gr.HTML(f"<div class='kpi'><div class='value'>{int(df['survived'].sum()):,}</div><div class='label'>Overlevenden</div></div>")
|
| 289 |
+
gr.HTML(f"<div class='kpi'><div class='value'>{df['survived'].mean()*100:.1f}%</div><div class='label'>% Overleefd</div></div>")
|
| 290 |
+
gr.HTML(f"<div class='kpi'><div class='value'>{', '.join(map(str, sorted(df['pclass'].unique())))}</div><div class='label'>Klassen</div></div>")
|
| 291 |
|
| 292 |
+
# Overige visualisaties
|
| 293 |
gr.Markdown("## 📊 Verken de data", elem_classes=["panel"])
|
| 294 |
with gr.Row():
|
| 295 |
g2 = gr.Plot(label="Leeftijdsverdeling per status")
|
|
|
|
| 297 |
with gr.Row():
|
| 298 |
g4 = gr.Plot(label="Ticketprijs per klasse")
|
| 299 |
|
| 300 |
+
# Interactieve voorspelling
|
| 301 |
+
with gr.Column(elem_classes=["panel"]):
|
| 302 |
+
# Tekstblok + gauge naast elkaar
|
| 303 |
+
with gr.Row():
|
| 304 |
+
with gr.Column(scale=2, min_width=420):
|
| 305 |
+
gr.Markdown("""## 🔮 Jouw scenario — bereken je overlevingskans en lees je scène
|
| 306 |
+
Hier kun je ontdekken **hoe groot jouw kans op overleving** zou zijn geweest aan boord van de *Titanic* — en meteen het **verhaal van jouw nacht** lezen.
|
| 307 |
+
1. **Kies je profiel**
|
| 308 |
+
- **Klasse:** 1e, 2e of 3e klasse (je reiscomfort en dekpositie).
|
| 309 |
+
- **Geslacht:** man of vrouw — dit had invloed op reddingsvoorrang.
|
| 310 |
+
- **Leeftijd:** jouw leeftijd in jaren.
|
| 311 |
+
- **Broers/zussen** en **ouders/kinderen**: hoeveel familieleden reisden met je mee.
|
| 312 |
+
- **Ticketprijs (£):** hoe duur je passage was.
|
| 313 |
+
- **Vertrekhaven:** Cherbourg (C), Queenstown (Q) of Southampton (S).
|
| 314 |
+
2. **Klik op de knop “🎲 Bereken én vertel mijn verhaal”**
|
| 315 |
+
Het model schat jouw **overlevingskans** op basis van historische patronen.
|
| 316 |
+
3. **Lees je persoonlijke scène**
|
| 317 |
+
Onder de knop verschijnt een korte beschrijving die je meeneemt naar die nacht —
|
| 318 |
+
gebaseerd op jouw ingevulde profiel en de berekende kans.
|
| 319 |
+
> 💡 *De voorspelling is een statistische schatting, geen oordeel.
|
| 320 |
+
> Ze helpt je zien hoe factoren zoals klasse, geslacht en leeftijd destijds iemands lot konden bepalen.*""")
|
| 321 |
+
with gr.Column(scale=1, min_width=320):
|
| 322 |
+
viz_plot = gr.Plot(label="Jouw overlevingskans (live)")
|
| 323 |
+
|
| 324 |
+
with gr.Row():
|
| 325 |
+
ui_pclass = gr.Slider(1, 3, value=2, step=1, label="Klasse (1=1e, 3=3e)")
|
| 326 |
+
ui_sex = gr.Radio(["Man","Vrouw"], value="Man", label="Geslacht")
|
| 327 |
+
ui_age = gr.Slider(0, 80, value=30, label="Leeftijd")
|
| 328 |
+
with gr.Row():
|
| 329 |
+
ui_sibsp = gr.Slider(0, 8, value=1, step=1, label="Broers/Zussen aan boord")
|
| 330 |
+
ui_parch = gr.Slider(0, 6, value=0, step=1, label="Ouders/Kinder(en) aan boord")
|
| 331 |
+
ui_fare = gr.Slider(0, 600, value=50, label="Ticketprijs (£)")
|
| 332 |
+
ui_emb = gr.Radio(["C","Q","S"], value="S", label="Vertrekhaven")
|
| 333 |
+
btn = gr.Button("🎲 Bereken én vertel mijn verhaal", variant="primary")
|
| 334 |
+
story_out = gr.Markdown()
|
| 335 |
+
|
| 336 |
+
# Loads & acties
|
| 337 |
demo.load(fn=train_and_embed_solid, inputs=[], outputs=[status_md, train_plot])
|
| 338 |
demo.load(lambda: (plot_age_hist(df), plot_gender(df), plot_fare_box(df)), inputs=[], outputs=[g2, g3, g4])
|
| 339 |
|
| 340 |
+
# Initiele gauge (na modeltraining): gebruik de default UI-waarden
|
| 341 |
+
demo.load(lambda: live_viz(2, "Man", 30, 1, 0, 50, "S"), inputs=[], outputs=[viz_plot])
|
| 342 |
+
|
| 343 |
+
# Live updates bij elke wijziging
|
| 344 |
+
for comp in [ui_pclass, ui_sex, ui_age, ui_sibsp, ui_parch, ui_fare, ui_emb]:
|
| 345 |
+
comp.change(live_viz,
|
| 346 |
+
inputs=[ui_pclass, ui_sex, ui_age, ui_sibsp, ui_parch, ui_fare, ui_emb],
|
| 347 |
+
outputs=viz_plot)
|
| 348 |
+
|
| 349 |
+
# Ook updaten bij de knop
|
| 350 |
+
btn.click(predict_and_story,
|
| 351 |
+
inputs=[ui_pclass, ui_sex, ui_age, ui_sibsp, ui_parch, ui_fare, ui_emb],
|
| 352 |
+
outputs=story_out)
|
| 353 |
+
btn.click(live_viz,
|
| 354 |
+
inputs=[ui_pclass, ui_sex, ui_age, ui_sibsp, ui_parch, ui_fare, ui_emb],
|
| 355 |
+
outputs=viz_plot)
|
| 356 |
+
|
| 357 |
demo.launch()
|