Marcel0123 commited on
Commit
7f76c44
·
verified ·
1 Parent(s): 9f59116

Upload 2 files

Browse files
Files changed (1) hide show
  1. app.py +74 -291
app.py CHANGED
@@ -7,7 +7,7 @@ from sklearn import datasets
7
  from sklearn.preprocessing import StandardScaler
8
  from sklearn.decomposition import PCA
9
  import plotly.graph_objects as go
10
- import time
11
 
12
  FEATURE_LABELS = {
13
  "age": "Leeftijd",
@@ -24,31 +24,6 @@ FEATURE_LABELS = {
24
  }
25
  LABEL_TO_KEY = {v: k for k, v in FEATURE_LABELS.items()}
26
 
27
- MEDICAL_MD = """
28
- ### Medisch nut
29
-
30
- **Wat zien we hier?**
31
- Ik heb een bestaande, anonieme gezondheidsdataset gebruikt die speciaal beschikbaar is gemaakt voor onderzoek en studie. In deze gegevens staan metingen van een grote groep patiënten, zoals **bloedwaarden, BMI, cholesterol en bloedsuiker**.
32
-
33
- Zo'n enorme berg cijfers is voor artsen en ziekenhuizen bijna niet in één keer te overzien. Het is gewoon te veel om met het blote oog patronen uit te halen.
34
-
35
- **Daar komt kunstmatige intelligentie om de hoek kijken.**
36
- Met deze techniek (PCA) kan de computer de data slim samenvatten en patronen zichtbaar maken. Dit programma dat ik heb ontworpen laat live zien hoe die samenvatting werkt.
37
-
38
- - Elke punt is één patiënt.
39
- - De kleur laat zien hoe hoog of laag een bepaalde meting is (standaard: BMI).
40
- - De pijlen laten zien welke metingen het meeste invloed hebben.
41
- - Links bovenin kun je kiezen welke meting je als uitgangspunt wilt nemen.
42
-
43
- **En wat heb je hieraan?**
44
- In de praktijk gebruiken artsen en onderzoekers zo'n plot om patronen en verbanden te ontdekken. 👉 Het is dus niet alleen een mooi plaatje, maar echt een manier om grote hoeveelheden data sneller en slimmer te begrijpen.
45
-
46
- Met AI kunnen we patronen vinden die je met het blote oog nooit zou zien. Dat maakt dit niet alleen een mooie visualisatie, maar ook een knap stukje technologie met échte waarde voor onderzoek en zorg.
47
-
48
- **Speel zelf de onderzoeker!**
49
- Doe alsof je een arts bent en kies links bovenin een waarde, bijvoorbeeld **cholesterol**, **leeftijd** of **geslacht**. Klik daarna op *Update visualisaties* en ontdek je eigen patronen in de data.
50
- """
51
-
52
  def load_diabetes_df():
53
  d = datasets.load_diabetes()
54
  X = pd.DataFrame(d.data, columns=d.feature_names)
@@ -57,293 +32,101 @@ def load_diabetes_df():
57
  df["target"] = y
58
  return df
59
 
60
- def compute_overview_table(df: pd.DataFrame):
61
- keys = ["bmi","bp","s1","s2","s3","s4","s5","s6"]
62
- rows = []
63
- for k in keys:
64
- vals = df[k].dropna().values
65
- if vals.size == 0:
66
- continue
67
- mean = float(vals.mean())
68
- pct_above = float((vals > 0).mean() * 100.0) # standardized: 0 ~ mean
69
- pct_below = float((vals < 0).mean() * 100.0)
70
- rows.append({
71
- "Meting": FEATURE_LABELS.get(k, k),
72
- "Gemiddelde (gestandaardiseerd)": round(mean, 3),
73
- "% boven gemiddelde": round(pct_above, 1),
74
- "% onder gemiddelde": round(pct_below, 1),
75
- })
76
- table = pd.DataFrame(rows)
77
- note = ("Let op: waarden in deze dataset zijn **gestandaardiseerd**. "
78
- "`0` betekent ongeveer het **algemene gemiddelde**. "
79
- "Positief = hoger dan gemiddeld, negatief = lager dan gemiddeld.")
80
- return table, note
81
-
82
- def compute_top_correlations(df: pd.DataFrame, top_n: int = 6):
83
- feats = [c for c in df.columns if c != "target"]
84
- corr = pd.DataFrame(df[feats]).corr()
85
- pairs = []
86
- for i, a in enumerate(feats):
87
- for j, b in enumerate(feats):
88
- if j <= i:
89
- continue
90
- pairs.append({
91
- "Combinatie": f"{FEATURE_LABELS.get(a,a)} ↔ {FEATURE_LABELS.get(b,b)}",
92
- "Correlatie": corr.loc[a, b]
93
- })
94
- out = pd.DataFrame(pairs)
95
- out["Sterkte (|r|)"] = out["Correlatie"].abs()
96
- out = out.sort_values("Sterkte (|r|)", ascending=False).head(top_n).reset_index(drop=True)
97
- out["Correlatie"] = out["Correlatie"].round(3)
98
- out["Sterkte (|r|)"] = out["Sterkte (|r|)"].round(3)
99
- return out[["Combinatie", "Correlatie", "Sterkte (|r|)"]]
100
-
101
- def compute_pca(df: pd.DataFrame, n_components: int, standardize: bool):
102
  feats = [c for c in df.columns if c != "target"]
103
  X = df[feats].values
104
  if standardize:
105
- scaler = StandardScaler(with_mean=True, with_std=True)
106
  Xs = scaler.fit_transform(X)
107
  else:
108
  Xs = X
109
- pca = PCA(n_components=min(int(n_components), Xs.shape[1]))
110
  Z = pca.fit_transform(Xs)
111
  loadings = pca.components_.T
112
  expl = pca.explained_variance_ratio_
113
  return feats, Xs, Z, loadings, expl
114
 
115
- def build_biplot(Z, loadings, feats, color_vals, arrow_scale, point_size, alpha, color_label_nl):
116
- fig = plt.figure(figsize=(7.8, 5.6))
117
- ax = fig.add_subplot(111)
118
- sc = ax.scatter(Z[:, 0], Z[:, 1], c=color_vals, s=point_size, alpha=alpha)
119
- cbar = plt.colorbar(sc, ax=ax, pad=0.02)
120
- cbar.set_label(f"Kleur: {color_label_nl}")
121
- ax.set_xlabel("PC1"); ax.set_ylabel("PC2")
122
- ax.set_title("PCA-biplot — punten (patiënten) + pijlen (belangrijkste metingen)")
123
- for i, key in enumerate(feats):
124
- x_arrow = loadings[i, 0] * arrow_scale
125
- y_arrow = loadings[i, 1] * arrow_scale
126
- ax.arrow(0, 0, x_arrow, y_arrow, head_width=0.05, head_length=0.08, fc="k", ec="k", length_includes_head=True)
127
- ax.text(x_arrow * 1.08, y_arrow * 1.08, FEATURE_LABELS.get(key, key), fontsize=9, ha="center", va="center")
128
- ax.axhline(0, color="grey", linewidth=0.6, linestyle=":")
129
- ax.axvline(0, color="grey", linewidth=0.6, linestyle=":")
130
- ax.grid(True, linestyle=":", linewidth=0.6)
131
- plt.tight_layout()
 
 
 
 
 
 
132
  return fig
133
 
134
  def build_variance_plot(expl):
135
- fig = plt.figure(figsize=(7.8, 3.8))
136
  ax = fig.add_subplot(111)
137
- xs = np.arange(1, len(expl) + 1)
138
- ax.bar(xs, expl, width=0.8, align="center")
139
- ax.plot(xs, np.cumsum(expl), marker="o")
140
- ax.set_xticks(xs)
141
- ax.set_xlabel("Principal Component")
142
- ax.set_ylabel("Explained variance ratio")
143
- ax.set_title("Uitlegvariantie per component (balken) + cumulatief (lijn)")
144
- ax.grid(True, linestyle=":", linewidth=0.6)
145
- plt.tight_layout()
146
  return fig
147
 
148
- def build_pca3d(Z3, color_vals, color_label_nl, point_size, alpha):
149
- # Plotly 3D scatter for real rotation/drag
150
- fig = go.Figure(data=[go.Scatter3d(
151
- x=Z3[:, 0], y=Z3[:, 1], z=Z3[:, 2],
152
- mode="markers",
153
- marker=dict(size=max(2, int(point_size/2)), color=color_vals, opacity=alpha)
154
- )])
155
- fig.update_layout(
156
- title="PCA 3D — PC1 · PC2 · PC3",
157
- scene=dict(xaxis_title="PC1", yaxis_title="PC2", zaxis_title="PC3"),
158
- margin=dict(l=0, r=0, t=40, b=0),
159
- height=520
160
- )
161
  return fig
162
 
163
- def pca_biplot(color_label="BMI (Body Mass Index)", arrow_scale=2.0, point_size=32, alpha=0.85, n_components=10, standardize=True, show_3d=False):
164
- df = load_diabetes_df()
165
- overview_df, overview_note = compute_overview_table(df)
166
- corr_tbl = compute_top_correlations(df)
167
-
168
- feats, Xs, Z, loadings, expl = compute_pca(df, n_components, standardize)
169
- color_key = LABEL_TO_KEY.get(color_label, "bmi")
170
- color_label_nl = FEATURE_LABELS.get(color_key, color_key)
171
- color_vals = df[color_key].values
172
-
173
- fig1 = build_biplot(Z, loadings, feats, color_vals, arrow_scale, point_size, alpha, color_label_nl)
174
- fig2 = build_variance_plot(expl)
175
-
176
- load_df = pd.DataFrame({
177
- "feature_key": feats,
178
- "PC1_loading": loadings[:, 0],
179
- "PC2_loading": loadings[:, 1],
180
- "PC1_abs": np.abs(loadings[:, 0]),
181
- "PC2_abs": np.abs(loadings[:, 1]),
182
- })
183
- load_df["Feature (PC1)"] = load_df["feature_key"].map(lambda k: FEATURE_LABELS.get(k, k))
184
- load_df["Feature (PC2)"] = load_df["feature_key"].map(lambda k: FEATURE_LABELS.get(k, k))
185
- top_pc1 = load_df.sort_values("PC1_abs", ascending=False)[["Feature (PC1)", "PC1_loading"]].head(6).reset_index(drop=True)
186
- top_pc2 = load_df.sort_values("PC2_abs", ascending=False)[["Feature (PC2)", "PC2_loading"]].head(6).reset_index(drop=True)
187
- max_len = max(len(top_pc1), len(top_pc2))
188
- top_pc1 = top_pc1.reindex(range(max_len)); top_pc2 = top_pc2.reindex(range(max_len))
189
- table = pd.concat([top_pc1, top_pc2], axis=1)
190
 
191
- summary_md = f"""
192
- ### Wat zie je hier?
193
- - **Punten (patiënten)** geprojecteerd in 2D met **PCA**. Dicht bij elkaar = **lijken op elkaar** over meerdere metingen.
194
- - **Kleur** = **{color_label_nl}**. Zo zie je meteen of deze eigenschap een **gradiënt** vormt.
195
- - **Pijlen** = bijdrage van **metingen** aan de richting van **PC1/PC2**. **Langere pijlen** wegen zwaarder.
196
- - **Balkgrafiek** = per component hoeveel variatie hij uitlegt; **lijn** = cumulatief.
197
- """
198
-
199
- # 3D
200
- if show_3d:
201
- # Zorg dat we minstens 3 componenten hebben
202
- if Z.shape[1] < 3:
203
- pca3 = PCA(n_components=3)
204
- Z3 = pca3.fit_transform(Xs)
205
- else:
206
- Z3 = Z[:, :3]
207
- fig3 = build_pca3d(Z3, color_vals, color_label_nl, point_size, alpha)
208
- pca3d_out = gr.update(value=fig3, visible=True)
209
- else:
210
- pca3d_out = gr.update(value=None, visible=False)
211
-
212
- return fig1, fig2, table, summary_md, overview_df, overview_note, corr_tbl, pca3d_out
213
-
214
- def animate_pca(color_label="BMI (Body Mass Index)", point_size=32, alpha=0.85, n_components=10, standardize=True, frames=40, pause=0.0):
215
  df = load_diabetes_df()
216
  feats, Xs, Z, loadings, expl = compute_pca(df, n_components, standardize)
217
- color_key = LABEL_TO_KEY.get(color_label, "bmi")
218
- color_vals = df[color_key].values
219
- for i in range(frames):
220
- t = i / max(1, frames-1)
221
- w1 = min(1.0, t * 2.0)
222
- w2 = max(0.0, (t - 0.5) * 2.0)
223
- coords = np.column_stack([Z[:, 0] * w1, Z[:, 1] * w2])
224
- fig = plt.figure(figsize=(7.8, 5.6))
225
- ax = fig.add_subplot(111)
226
- ax.scatter(coords[:, 0], coords[:, 1], c=color_vals, s=point_size, alpha=alpha)
227
- ax.set_xlabel("PC1 (opbouw)"); ax.set_ylabel("PC2 (opbouw)")
228
- title = "PCA-projectie (animatie) — " + ("PC1 →" if w2 == 0 else "PC1 + PC2")
229
- ax.set_title(f"{title} frame {i+1}/{frames}")
230
- ax.axhline(0, color="grey", linewidth=0.6, linestyle=":")
231
- ax.axvline(0, color="grey", linewidth=0.6, linestyle=":")
232
- ax.grid(True, linestyle=":", linewidth=0.6)
233
- plt.tight_layout()
234
- yield fig
235
- if pause > 0:
236
- time.sleep(pause)
237
-
238
- def export_biplot_png(color_label="BMI (Body Mass Index)", arrow_scale=2.0, point_size=32, alpha=0.85, n_components=10, standardize=True):
239
- df = load_diabetes_df()
240
- feats, Xs, Z, loadings, expl = compute_pca(df, n_components, standardize)
241
- color_key = LABEL_TO_KEY.get(color_label, "bmi")
242
- color_label_nl = FEATURE_LABELS.get(color_key, color_key)
243
- color_vals = df[color_key].values
244
- fig = build_biplot(Z, loadings, feats, color_vals, arrow_scale, point_size, alpha, color_label_nl)
245
- path = f"/mnt/data/biplot_{int(time.time())}.png"
246
- fig.savefig(path, dpi=150, bbox_inches="tight")
247
- plt.close(fig)
248
- return path
249
-
250
- def export_variance_png(n_components=10, standardize=True):
251
- df = load_diabetes_df()
252
- feats, Xs, Z, loadings, expl = compute_pca(df, n_components, standardize)
253
- fig = build_variance_plot(expl)
254
- path = f"/mnt/data/variance_{int(time.time())}.png"
255
- fig.savefig(path, dpi=150, bbox_inches="tight")
256
- plt.close(fig)
257
- return path
258
-
259
- with gr.Blocks(title="PCA Biplot — Diabetes (Dashboard)") as demo:
260
- gr.HTML("""
261
- <style>
262
- .card {background:#fff; border:1px solid #e5e7eb; border-radius:12px; padding:14px; box-shadow: 0 1px 4px rgba(0,0,0,0.06);}
263
- .callout {padding:12px 14px; border-left:4px solid #2563eb; background:#f1f5f9; border-radius:8px; margin: 8px 0 18px;}
264
- .smallnote {font-size: 0.92em; opacity: 0.85;}
265
- </style>
266
- """)
267
-
268
- gr.Markdown("# PCA Biplot — Diabetes (Dashboard)")
269
- gr.Markdown(MEDICAL_MD)
270
-
271
  with gr.Row():
272
- with gr.Column(scale=1):
273
- with gr.Group():
274
- gr.Markdown("### Instellingen")
275
- color_choices = [FEATURE_LABELS[k] for k in ["bmi","bp","s1","s2","s3","s4","s5","s6","age","sex","target"]]
276
- color_feat = gr.Dropdown(choices=color_choices, value=FEATURE_LABELS["bmi"], label="Kleur op meting")
277
- arrow_scale = gr.Slider(0.5, 5.0, value=2.0, step=0.1, label="Pijl-schaal (loadings)")
278
- point_size = gr.Slider(8, 80, value=32, step=2, label="Puntgrootte")
279
- alpha = gr.Slider(0.2, 1.0, value=0.85, step=0.05, label="Transparantie (punten)")
280
- n_components = gr.Slider(2, 10, value=10, step=1, label="Aantal PCA-componenten")
281
- standardize = gr.Checkbox(value=True, label="Standaardiseer metingen (aanbevolen)")
282
- show_3d = gr.Checkbox(value=True, label="Toon 3D PCA (PC1–PC3)")
283
- run_btn = gr.Button("Update visualisaties")
284
- gr.HTML('<div class="callout smallnote">💡 <b>Tip:</b> Kies links een meting (bijv. BMI of cholesterol) en klik daarna op <b>Update visualisaties</b>.</div>')
285
- with gr.Group():
286
- gr.Markdown("### Animatie")
287
- animate_btn = gr.Button("▶ Animate PCA (PC1 → PC2)")
288
- anim_plot = gr.Plot(label="Animatie van projectie")
289
-
290
- with gr.Group():
291
- gr.Markdown("### Downloads")
292
- dl_biplot = gr.DownloadButton("Download biplot (PNG)")
293
- dl_var = gr.DownloadButton("Download variatieplot (PNG)")
294
- file_biplot = gr.File(label="Biplot PNG", visible=False)
295
- file_var = gr.File(label="Variatieplot PNG", visible=False)
296
-
297
- with gr.Column(scale=2):
298
- with gr.Row():
299
- with gr.Column():
300
- gr.Markdown("### Biplot (2D)")
301
- plot_biplot = gr.Plot()
302
- with gr.Column():
303
- gr.Markdown("### Uitlegvariantie")
304
- plot_expl = gr.Plot()
305
- with gr.Row():
306
- with gr.Column():
307
- gr.Markdown("### Top-features (PC1 / PC2)")
308
- table = gr.Dataframe(headers=["Feature (PC1)", "Loading PC1", "Feature (PC2)", "Loading PC2"], row_count=6)
309
- with gr.Column():
310
- gr.Markdown("### Overzicht (gemiddelden & verdeling)")
311
- overview_tbl = gr.Dataframe(interactive=False)
312
- overview_note_md = gr.Markdown()
313
- with gr.Row():
314
- with gr.Column():
315
- gr.Markdown("### Samenvatting")
316
- summary = gr.Markdown()
317
- with gr.Column():
318
- gr.Markdown("### Top correlaties (features)")
319
- topcorr_tbl = gr.Dataframe(interactive=False)
320
- with gr.Row():
321
- with gr.Column():
322
- gr.Markdown("### 3D PCA (PC1–PC3 — sleep om te draaien)")
323
- plot3d = gr.Plot(visible=True)
324
-
325
- inputs = [color_feat, arrow_scale, point_size, alpha, n_components, standardize, show_3d]
326
- run_btn.click(fn=pca_biplot, inputs=inputs,
327
- outputs=[plot_biplot, plot_expl, table, summary, overview_tbl, overview_note_md, topcorr_tbl, plot3d])
328
- demo.load(fn=pca_biplot, inputs=inputs,
329
- outputs=[plot_biplot, plot_expl, table, summary, overview_tbl, overview_note_md, topcorr_tbl, plot3d])
330
-
331
- animate_btn.click(fn=animate_pca,
332
- inputs=[color_feat, point_size, alpha, n_components, standardize],
333
- outputs=anim_plot)
334
 
335
- dl_biplot.click(fn=export_biplot_png,
336
- inputs=[color_feat, arrow_scale, point_size, alpha, n_components, standardize],
337
- outputs=[dl_biplot])
338
- dl_biplot.click(fn=export_biplot_png,
339
- inputs=[color_feat, arrow_scale, point_size, alpha, n_components, standardize],
340
- outputs=[file_biplot])
341
- dl_var.click(fn=export_variance_png,
342
- inputs=[n_components, standardize],
343
- outputs=[dl_var])
344
- dl_var.click(fn=export_variance_png,
345
- inputs=[n_components, standardize],
346
- outputs=[file_var])
347
 
348
- if __name__ == "__main__":
349
- demo.queue().launch(server_name="0.0.0.0", server_port=7860, ssr_mode=False, show_api=False)
 
7
  from sklearn.preprocessing import StandardScaler
8
  from sklearn.decomposition import PCA
9
  import plotly.graph_objects as go
10
+ import plotly.express as px
11
 
12
  FEATURE_LABELS = {
13
  "age": "Leeftijd",
 
24
  }
25
  LABEL_TO_KEY = {v: k for k, v in FEATURE_LABELS.items()}
26
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  def load_diabetes_df():
28
  d = datasets.load_diabetes()
29
  X = pd.DataFrame(d.data, columns=d.feature_names)
 
32
  df["target"] = y
33
  return df
34
 
35
+ def compute_pca(df, n_components=10, standardize=True):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  feats = [c for c in df.columns if c != "target"]
37
  X = df[feats].values
38
  if standardize:
39
+ scaler = StandardScaler()
40
  Xs = scaler.fit_transform(X)
41
  else:
42
  Xs = X
43
+ pca = PCA(n_components=min(n_components, Xs.shape[1]))
44
  Z = pca.fit_transform(Xs)
45
  loadings = pca.components_.T
46
  expl = pca.explained_variance_ratio_
47
  return feats, Xs, Z, loadings, expl
48
 
49
+ def build_biplot(df, Z, loadings, feats, color_key):
50
+ hover_text = []
51
+ for idx in range(len(df)):
52
+ parts = [f"{FEATURE_LABELS.get(k,k)}: {df.iloc[idx][k]:.3f}" for k in df.columns]
53
+ hover_text.append("<br>".join(parts))
54
+ fig = go.Figure()
55
+ fig.add_trace(go.Scatter(x=Z[:,0], y=Z[:,1], mode="markers",
56
+ marker=dict(size=7, color=df[color_key].values),
57
+ text=hover_text,
58
+ hovertemplate="%{text}<extra></extra>"))
59
+ # arrows
60
+ scale=2.0
61
+ for i,key in enumerate(feats):
62
+ x = loadings[i,0]*scale; y = loadings[i,1]*scale
63
+ fig.add_annotation(x=x, y=y, ax=0, ay=0, showarrow=True, arrowhead=3)
64
+ fig.add_annotation(x=x*1.05, y=y*1.05, text=FEATURE_LABELS.get(key,key), showarrow=False, font=dict(size=10))
65
+ fig.update_layout(title="PCA-biplot (2D, hover)", xaxis_title="PC1", yaxis_title="PC2", height=500)
66
+ return fig
67
+
68
+ def build_pca3d(Z3, color_vals):
69
+ fig = go.Figure(data=[go.Scatter3d(x=Z3[:,0], y=Z3[:,1], z=Z3[:,2], mode="markers",
70
+ marker=dict(size=4,color=color_vals,opacity=0.85))])
71
+ fig.update_layout(title="PCA 3D", scene=dict(xaxis_title="PC1", yaxis_title="PC2", zaxis_title="PC3"), height=500)
72
  return fig
73
 
74
  def build_variance_plot(expl):
75
+ fig = plt.figure()
76
  ax = fig.add_subplot(111)
77
+ xs = np.arange(1,len(expl)+1)
78
+ ax.bar(xs, expl); ax.plot(xs, np.cumsum(expl), marker="o")
79
+ ax.set_xlabel("PC"); ax.set_ylabel("Explained variance ratio")
80
+ fig.tight_layout()
 
 
 
 
 
81
  return fig
82
 
83
+ def build_corr_heatmap(df):
84
+ feats = [c for c in df.columns if c != "target"]
85
+ corr = pd.DataFrame(df[feats]).corr()
86
+ order = corr.abs().sum().sort_values(ascending=False).index.tolist()
87
+ corr_sorted = corr.loc[order, order]
88
+ fig = px.imshow(corr_sorted, color_continuous_scale="RdBu", origin="lower", zmin=-1, zmax=1)
89
+ fig.update_layout(title="Correlatie-heatmap")
 
 
 
 
 
 
90
  return fig
91
 
92
+ def build_hist_box(df, color_key):
93
+ series = df[color_key]
94
+ fig_hist = px.histogram(series, nbins=30, title=f"Histogram — {FEATURE_LABELS.get(color_key,color_key)}")
95
+ fig_box = px.box(series, points="outliers", title=f"Boxplot — {FEATURE_LABELS.get(color_key,color_key)}")
96
+ return fig_hist, fig_box
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
 
98
+ def controller(color_label="BMI (Body Mass Index)", n_components=10, standardize=True):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
  df = load_diabetes_df()
100
  feats, Xs, Z, loadings, expl = compute_pca(df, n_components, standardize)
101
+ color_key = LABEL_TO_KEY[color_label]
102
+ fig2d = build_biplot(df, Z, loadings, feats, color_key)
103
+ if Z.shape[1] < 3:
104
+ pca3 = PCA(n_components=3); Z3 = pca3.fit_transform(Xs)
105
+ else:
106
+ Z3 = Z[:,:3]
107
+ fig3d = build_pca3d(Z3, df[color_key].values)
108
+ fig_var = build_variance_plot(expl)
109
+ fig_heat = build_corr_heatmap(df)
110
+ fig_hist, fig_box = build_hist_box(df, color_key)
111
+ return fig2d, fig3d, fig_var, fig_heat, fig_hist, fig_box
112
+
113
+ with gr.Blocks() as demo:
114
+ gr.Markdown("# PCA Dashboard — Diabetes")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
  with gr.Row():
116
+ color_feat = gr.Dropdown(choices=list(LABEL_TO_KEY.keys()), value="BMI (Body Mass Index)", label="Kleur op meting")
117
+ n_components = gr.Slider(3,10,10,step=1,label="Aantal PCA-componenten")
118
+ standardize = gr.Checkbox(value=True,label="Standaardiseer")
119
+ run_btn = gr.Button("Update")
120
+ with gr.Row():
121
+ plot2d = gr.Plot(); plot3d = gr.Plot()
122
+ with gr.Row():
123
+ plot_var = gr.Plot(); plot_heat = gr.Plot()
124
+ with gr.Row():
125
+ plot_hist = gr.Plot(); plot_box = gr.Plot()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
 
127
+ inputs=[color_feat,n_components,standardize]
128
+ run_btn.click(fn=controller, inputs=inputs, outputs=[plot2d,plot3d,plot_var,plot_heat,plot_hist,plot_box])
129
+ demo.load(fn=controller, inputs=inputs, outputs=[plot2d,plot3d,plot_var,plot_heat,plot_hist,plot_box])
 
 
 
 
 
 
 
 
 
130
 
131
+ if __name__=="__main__":
132
+ demo.queue().launch(server_name="0.0.0.0", server_port=7860)