Spaces:
Running
Running
Commit
路
d966a8e
1
Parent(s):
ed8f744
Minor Changes
Browse files
app.py
CHANGED
@@ -2,7 +2,7 @@ import streamlit as st
|
|
2 |
import pandas as pd
|
3 |
import numpy as np
|
4 |
from bokeh.plotting import figure
|
5 |
-
from bokeh.models import ColumnDataSource, DataTable, TableColumn, CustomJS, Select
|
6 |
from bokeh.layouts import row, column
|
7 |
from bokeh.palettes import Reds9, Blues9
|
8 |
from sklearn.decomposition import PCA
|
@@ -62,21 +62,21 @@ def add_dataset_to_fig(fig, df, selected_labels, marker, color_mapping):
|
|
62 |
fill_color=color, line_color=color,
|
63 |
legend_label=f"{label} (Real)")
|
64 |
elif marker == "square":
|
65 |
-
r = fig.square('x', 'y', size=
|
66 |
fill_color=color, line_color=color,
|
67 |
legend_label=f"{label} (Synthetic)")
|
68 |
renderers[label] = r
|
69 |
return renderers
|
70 |
|
71 |
def get_color_maps(selected_subsets: dict):
|
72 |
-
# Para real
|
73 |
num_real = len(selected_subsets["real"])
|
74 |
red_palette = Reds9[:num_real] if num_real <= 9 else (Reds9 * ((num_real // 9) + 1))[:num_real]
|
75 |
color_mapping_real = {label: red_palette[i] for i, label in enumerate(sorted(selected_subsets["real"]))}
|
76 |
-
|
77 |
num_es = len(selected_subsets["es-digital-seq"])
|
78 |
blue_palette = Blues9[:num_es] if num_es <= 9 else (Blues9 * ((num_es // 9) + 1))[:num_es]
|
79 |
color_mapping_es = {label: blue_palette[i] for i, label in enumerate(sorted(selected_subsets["es-digital-seq"]))}
|
|
|
80 |
return {"real": color_mapping_real, "es-digital-seq": color_mapping_es}
|
81 |
|
82 |
def split_versions(df_combined, reduced):
|
@@ -94,7 +94,7 @@ def subset_selectors(unique_subsets: dict):
|
|
94 |
return {"real": selected_real, "es-digital-seq": selected_es}
|
95 |
|
96 |
def create_figure(dfs_reduced, selected_subsets: dict, color_maps: dict):
|
97 |
-
fig = figure(width=
|
98 |
real_renderers = add_dataset_to_fig(fig, dfs_reduced["real"], selected_subsets["real"],
|
99 |
marker="circle", color_mapping=color_maps["real"])
|
100 |
synthetic_renderers = add_dataset_to_fig(fig, dfs_reduced["es-digital-seq"], selected_subsets["es-digital-seq"],
|
@@ -138,7 +138,7 @@ def main():
|
|
138 |
centers_es = calculate_cluster_centers(dfs_reduced["es-digital-seq"], selected_subsets["es-digital-seq"])
|
139 |
df_distances = compute_distances(centers_es, centers_real)
|
140 |
|
141 |
-
#
|
142 |
df_table = df_distances.copy()
|
143 |
df_table.reset_index(inplace=True)
|
144 |
df_table.rename(columns={'index': 'Synthetic'}, inplace=True)
|
@@ -147,12 +147,15 @@ def main():
|
|
147 |
for col in df_table.columns:
|
148 |
if col != 'Synthetic':
|
149 |
columns.append(TableColumn(field=col, title=col))
|
150 |
-
data_table = DataTable(source=source_table, columns=columns, width=400, height=300)
|
151 |
|
152 |
-
#
|
153 |
real_subset_names = list(df_table.columns[1:]) # todas las columnas excepto 'Synthetic'
|
154 |
real_select = Select(title="Select Real Subset:", value=real_subset_names[0], options=real_subset_names)
|
155 |
|
|
|
|
|
|
|
156 |
# Fuente para la l铆nea que conecta los centros
|
157 |
line_source = ColumnDataSource(data={'x': [], 'y': []})
|
158 |
fig.line('x', 'y', source=line_source, line_width=2, line_color='black')
|
@@ -161,7 +164,7 @@ def main():
|
|
161 |
synthetic_centers_js = {k: [v[0], v[1]] for k, v in centers_es.items()}
|
162 |
real_centers_js = {k: [v[0], v[1]] for k, v in centers_real.items()}
|
163 |
|
164 |
-
# Callback para actualizar la
|
165 |
callback = CustomJS(args=dict(source=source_table, line_source=line_source,
|
166 |
synthetic_centers=synthetic_centers_js,
|
167 |
real_centers=real_centers_js,
|
@@ -182,7 +185,6 @@ def main():
|
|
182 |
line_source.data = { 'x': [syn_coords[0], real_coords[0]], 'y': [syn_coords[1], real_coords[1]] };
|
183 |
line_source.change.emit();
|
184 |
|
185 |
-
// Actualizar colores: resaltar 煤nicamente los puntos implicados
|
186 |
for (var key in synthetic_renderers) {
|
187 |
if (synthetic_renderers.hasOwnProperty(key)) {
|
188 |
var renderer = synthetic_renderers[key];
|
@@ -208,7 +210,6 @@ def main():
|
|
208 |
}
|
209 |
}
|
210 |
} else {
|
211 |
-
// Sin selecci贸n: reiniciar l铆nea y colores
|
212 |
line_source.data = { 'x': [], 'y': [] };
|
213 |
line_source.change.emit();
|
214 |
for (var key in synthetic_renderers) {
|
@@ -228,12 +229,37 @@ def main():
|
|
228 |
}
|
229 |
""")
|
230 |
|
231 |
-
# Asociamos el callback a los cambios en la selecci贸n de filas y en el dropdown
|
232 |
source_table.selected.js_on_change('indices', callback)
|
233 |
real_select.js_on_change('value', callback)
|
234 |
|
235 |
-
#
|
236 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
237 |
st.bokeh_chart(layout)
|
238 |
|
239 |
if __name__ == "__main__":
|
|
|
2 |
import pandas as pd
|
3 |
import numpy as np
|
4 |
from bokeh.plotting import figure
|
5 |
+
from bokeh.models import ColumnDataSource, DataTable, TableColumn, CustomJS, Select, Button
|
6 |
from bokeh.layouts import row, column
|
7 |
from bokeh.palettes import Reds9, Blues9
|
8 |
from sklearn.decomposition import PCA
|
|
|
62 |
fill_color=color, line_color=color,
|
63 |
legend_label=f"{label} (Real)")
|
64 |
elif marker == "square":
|
65 |
+
r = fig.square('x', 'y', size=6, source=source,
|
66 |
fill_color=color, line_color=color,
|
67 |
legend_label=f"{label} (Synthetic)")
|
68 |
renderers[label] = r
|
69 |
return renderers
|
70 |
|
71 |
def get_color_maps(selected_subsets: dict):
|
|
|
72 |
num_real = len(selected_subsets["real"])
|
73 |
red_palette = Reds9[:num_real] if num_real <= 9 else (Reds9 * ((num_real // 9) + 1))[:num_real]
|
74 |
color_mapping_real = {label: red_palette[i] for i, label in enumerate(sorted(selected_subsets["real"]))}
|
75 |
+
|
76 |
num_es = len(selected_subsets["es-digital-seq"])
|
77 |
blue_palette = Blues9[:num_es] if num_es <= 9 else (Blues9 * ((num_es // 9) + 1))[:num_es]
|
78 |
color_mapping_es = {label: blue_palette[i] for i, label in enumerate(sorted(selected_subsets["es-digital-seq"]))}
|
79 |
+
|
80 |
return {"real": color_mapping_real, "es-digital-seq": color_mapping_es}
|
81 |
|
82 |
def split_versions(df_combined, reduced):
|
|
|
94 |
return {"real": selected_real, "es-digital-seq": selected_es}
|
95 |
|
96 |
def create_figure(dfs_reduced, selected_subsets: dict, color_maps: dict):
|
97 |
+
fig = figure(width=400, height=400, tooltips=TOOLTIPS, title="")
|
98 |
real_renderers = add_dataset_to_fig(fig, dfs_reduced["real"], selected_subsets["real"],
|
99 |
marker="circle", color_mapping=color_maps["real"])
|
100 |
synthetic_renderers = add_dataset_to_fig(fig, dfs_reduced["es-digital-seq"], selected_subsets["es-digital-seq"],
|
|
|
138 |
centers_es = calculate_cluster_centers(dfs_reduced["es-digital-seq"], selected_subsets["es-digital-seq"])
|
139 |
df_distances = compute_distances(centers_es, centers_real)
|
140 |
|
141 |
+
# Tabla de distancias: se muestran todas las combinaciones
|
142 |
df_table = df_distances.copy()
|
143 |
df_table.reset_index(inplace=True)
|
144 |
df_table.rename(columns={'index': 'Synthetic'}, inplace=True)
|
|
|
147 |
for col in df_table.columns:
|
148 |
if col != 'Synthetic':
|
149 |
columns.append(TableColumn(field=col, title=col))
|
150 |
+
data_table = DataTable(source=source_table, columns=columns, width=400, height=300)
|
151 |
|
152 |
+
# Widget Select para elegir el subset real (columnas de la tabla)
|
153 |
real_subset_names = list(df_table.columns[1:]) # todas las columnas excepto 'Synthetic'
|
154 |
real_select = Select(title="Select Real Subset:", value=real_subset_names[0], options=real_subset_names)
|
155 |
|
156 |
+
# Bot贸n para resetear la visualizaci贸n a colores originales
|
157 |
+
reset_button = Button(label="Reset Colors", button_type="primary")
|
158 |
+
|
159 |
# Fuente para la l铆nea que conecta los centros
|
160 |
line_source = ColumnDataSource(data={'x': [], 'y': []})
|
161 |
fig.line('x', 'y', source=line_source, line_width=2, line_color='black')
|
|
|
164 |
synthetic_centers_js = {k: [v[0], v[1]] for k, v in centers_es.items()}
|
165 |
real_centers_js = {k: [v[0], v[1]] for k, v in centers_real.items()}
|
166 |
|
167 |
+
# Callback para actualizar la visualizaci贸n seg煤n la selecci贸n de la tabla y el dropdown
|
168 |
callback = CustomJS(args=dict(source=source_table, line_source=line_source,
|
169 |
synthetic_centers=synthetic_centers_js,
|
170 |
real_centers=real_centers_js,
|
|
|
185 |
line_source.data = { 'x': [syn_coords[0], real_coords[0]], 'y': [syn_coords[1], real_coords[1]] };
|
186 |
line_source.change.emit();
|
187 |
|
|
|
188 |
for (var key in synthetic_renderers) {
|
189 |
if (synthetic_renderers.hasOwnProperty(key)) {
|
190 |
var renderer = synthetic_renderers[key];
|
|
|
210 |
}
|
211 |
}
|
212 |
} else {
|
|
|
213 |
line_source.data = { 'x': [], 'y': [] };
|
214 |
line_source.change.emit();
|
215 |
for (var key in synthetic_renderers) {
|
|
|
229 |
}
|
230 |
""")
|
231 |
|
|
|
232 |
source_table.selected.js_on_change('indices', callback)
|
233 |
real_select.js_on_change('value', callback)
|
234 |
|
235 |
+
# Callback para el bot贸n de resetear: se reinician la l铆nea y los colores a su estado original.
|
236 |
+
reset_callback = CustomJS(args=dict(line_source=line_source,
|
237 |
+
synthetic_renderers=synthetic_renderers,
|
238 |
+
real_renderers=real_renderers,
|
239 |
+
synthetic_colors=color_maps["es-digital-seq"],
|
240 |
+
real_colors=color_maps["real"]),
|
241 |
+
code="""
|
242 |
+
line_source.data = { 'x': [], 'y': [] };
|
243 |
+
line_source.change.emit();
|
244 |
+
for (var key in synthetic_renderers) {
|
245 |
+
if (synthetic_renderers.hasOwnProperty(key)) {
|
246 |
+
var renderer = synthetic_renderers[key];
|
247 |
+
renderer.glyph.fill_color = synthetic_colors[key];
|
248 |
+
renderer.glyph.line_color = synthetic_colors[key];
|
249 |
+
}
|
250 |
+
}
|
251 |
+
for (var key in real_renderers) {
|
252 |
+
if (real_renderers.hasOwnProperty(key)) {
|
253 |
+
var renderer = real_renderers[key];
|
254 |
+
renderer.glyph.fill_color = real_colors[key];
|
255 |
+
renderer.glyph.line_color = real_colors[key];
|
256 |
+
}
|
257 |
+
}
|
258 |
+
""")
|
259 |
+
reset_button.js_on_event("button_click", reset_callback)
|
260 |
+
|
261 |
+
# Organizar el layout: gr谩fico, dropdown, bot贸n de reset y tabla
|
262 |
+
layout = column(fig, column(real_select, reset_button, data_table))
|
263 |
st.bokeh_chart(layout)
|
264 |
|
265 |
if __name__ == "__main__":
|