Spaces:
Running
Running
Commit
·
fa0575b
1
Parent(s):
703aeff
Improve Heatmap
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, Button, HoverTool, LinearColorMapper, ColorBar
|
6 |
from bokeh.layouts import column
|
7 |
from bokeh.palettes import Reds9, Blues9, Oranges9, Purples9, Greys9, BuGn9, Greens9
|
8 |
from sklearn.decomposition import PCA
|
@@ -12,6 +12,7 @@ import io
|
|
12 |
import ot
|
13 |
from sklearn.linear_model import LinearRegression
|
14 |
from scipy.stats import binned_statistic_2d
|
|
|
15 |
|
16 |
|
17 |
N_COMPONENTS = 2
|
@@ -1059,11 +1060,10 @@ def run_model(model_name):
|
|
1059 |
# --- INICIO DEL BLOQUE: Heatmap de características ---
|
1060 |
st.markdown("## Heatmap de Características")
|
1061 |
|
1062 |
-
# Cargar el CSV que contiene las características para el heatmap.
|
1063 |
-
# Se asume que el archivo se encuentra en "data/heatmaps.csv"
|
1064 |
try:
|
1065 |
-
df_heat = pd.read_csv("data/heatmaps.csv"
|
1066 |
-
|
|
|
1067 |
except Exception as e:
|
1068 |
st.error(f"Error al cargar heatmaps.csv: {e}")
|
1069 |
df_heat = None
|
@@ -1073,19 +1073,18 @@ def run_model(model_name):
|
|
1073 |
if 'img' not in df_all["real"].columns:
|
1074 |
st.error("La columna 'img' no se encuentra en las muestras reales para hacer el merge con heatmaps.csv.")
|
1075 |
else:
|
1076 |
-
# Crear la columna 'name' extrayendo el nombre
|
1077 |
df_all["real"]["name"] = df_all["real"]["img"].apply(
|
1078 |
lambda x: x.split("/")[-1].replace(".png", "") if isinstance(x, str) else x
|
1079 |
)
|
1080 |
-
print(df_all["real"]["name"])
|
1081 |
-
print(df_heat)
|
1082 |
|
1083 |
# Hacemos merge de las posiciones reales con el CSV de heatmaps usando la columna 'name'
|
1084 |
df_heatmap = pd.merge(df_all["real"], df_heat, on="name", how="inner")
|
1085 |
|
1086 |
# Extraemos las características disponibles (excluyendo 'name')
|
1087 |
feature_options = [col for col in df_heat.columns if col != "name"]
|
1088 |
-
selected_feature = st.selectbox("Seleccione la característica para el heatmap:",
|
|
|
1089 |
|
1090 |
# Determinar el rango de las posiciones (x, y) de las muestras reales
|
1091 |
x_min, x_max = df_heatmap['x'].min(), df_heatmap['x'].max()
|
@@ -1096,31 +1095,62 @@ def run_model(model_name):
|
|
1096 |
x_bins = np.linspace(x_min, x_max, grid_size + 1)
|
1097 |
y_bins = np.linspace(y_min, y_max, grid_size + 1)
|
1098 |
|
1099 |
-
#
|
1100 |
-
|
1101 |
-
|
1102 |
-
|
1103 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1104 |
|
1105 |
-
# La función image de Bokeh espera una lista de arrays
|
1106 |
-
heatmap_data = heat_stat.T
|
1107 |
|
1108 |
# Crear el mapa de color
|
1109 |
color_mapper = LinearColorMapper(palette="Viridis256", low=np.nanmin(heatmap_data), high=np.nanmax(heatmap_data))
|
1110 |
|
1111 |
-
# Crear la figura para el heatmap
|
1112 |
heatmap_fig = figure(title=f"Heatmap de '{selected_feature}'",
|
1113 |
x_range=(x_min, x_max), y_range=(y_min, y_max),
|
1114 |
width=600, height=600,
|
1115 |
tools="pan,wheel_zoom,reset,save", active_scroll="wheel_zoom")
|
|
|
1116 |
|
1117 |
-
# Dibujar el heatmap usando la imagen
|
1118 |
heatmap_fig.image(image=[heatmap_data], x=x_min, y=y_min,
|
1119 |
dw=x_max - x_min, dh=y_max - y_min,
|
1120 |
color_mapper=color_mapper)
|
1121 |
|
1122 |
-
#
|
1123 |
color_bar = ColorBar(color_mapper=color_mapper, location=(0, 0))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1124 |
heatmap_fig.add_layout(color_bar, 'right')
|
1125 |
|
1126 |
st.bokeh_chart(heatmap_fig)
|
|
|
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, HoverTool, LinearColorMapper, ColorBar, FuncTickFormatter
|
6 |
from bokeh.layouts import column
|
7 |
from bokeh.palettes import Reds9, Blues9, Oranges9, Purples9, Greys9, BuGn9, Greens9
|
8 |
from sklearn.decomposition import PCA
|
|
|
12 |
import ot
|
13 |
from sklearn.linear_model import LinearRegression
|
14 |
from scipy.stats import binned_statistic_2d
|
15 |
+
import json
|
16 |
|
17 |
|
18 |
N_COMPONENTS = 2
|
|
|
1060 |
# --- INICIO DEL BLOQUE: Heatmap de características ---
|
1061 |
st.markdown("## Heatmap de Características")
|
1062 |
|
|
|
|
|
1063 |
try:
|
1064 |
+
df_heat = pd.read_csv("data/heatmaps.csv")
|
1065 |
+
# Si fuera necesario, se pueden limpiar los nombres de las columnas:
|
1066 |
+
# df_heat.columns = [col.strip("'\"") for col in df_heat.columns]
|
1067 |
except Exception as e:
|
1068 |
st.error(f"Error al cargar heatmaps.csv: {e}")
|
1069 |
df_heat = None
|
|
|
1073 |
if 'img' not in df_all["real"].columns:
|
1074 |
st.error("La columna 'img' no se encuentra en las muestras reales para hacer el merge con heatmaps.csv.")
|
1075 |
else:
|
1076 |
+
# Crear la columna 'name' extrayendo el nombre final de la URL y removiendo ".png"
|
1077 |
df_all["real"]["name"] = df_all["real"]["img"].apply(
|
1078 |
lambda x: x.split("/")[-1].replace(".png", "") if isinstance(x, str) else x
|
1079 |
)
|
|
|
|
|
1080 |
|
1081 |
# Hacemos merge de las posiciones reales con el CSV de heatmaps usando la columna 'name'
|
1082 |
df_heatmap = pd.merge(df_all["real"], df_heat, on="name", how="inner")
|
1083 |
|
1084 |
# Extraemos las características disponibles (excluyendo 'name')
|
1085 |
feature_options = [col for col in df_heat.columns if col != "name"]
|
1086 |
+
selected_feature = st.selectbox("Seleccione la característica para el heatmap:",
|
1087 |
+
options=feature_options, key=f"heatmap_{model_name}")
|
1088 |
|
1089 |
# Determinar el rango de las posiciones (x, y) de las muestras reales
|
1090 |
x_min, x_max = df_heatmap['x'].min(), df_heatmap['x'].max()
|
|
|
1095 |
x_bins = np.linspace(x_min, x_max, grid_size + 1)
|
1096 |
y_bins = np.linspace(y_min, y_max, grid_size + 1)
|
1097 |
|
1098 |
+
# Si la variable seleccionada no es numérica, la convertimos a códigos numéricos
|
1099 |
+
# y guardamos la correspondencia para la leyenda.
|
1100 |
+
cat_mapping = None
|
1101 |
+
if not pd.api.types.is_numeric_dtype(df_heatmap[selected_feature]):
|
1102 |
+
cat = df_heatmap[selected_feature].astype('category')
|
1103 |
+
cat_mapping = list(cat.cat.categories)
|
1104 |
+
df_heatmap[selected_feature] = cat.cat.codes
|
1105 |
+
|
1106 |
+
# Intentamos calcular el heatmap; si falla, aplicamos la conversión a categoría
|
1107 |
+
try:
|
1108 |
+
heat_stat, x_edges, y_edges, binnumber = binned_statistic_2d(
|
1109 |
+
df_heatmap['x'], df_heatmap['y'], df_heatmap[selected_feature],
|
1110 |
+
statistic='mean', bins=[x_bins, y_bins]
|
1111 |
+
)
|
1112 |
+
except:
|
1113 |
+
cat = df_heatmap[selected_feature].astype('category')
|
1114 |
+
cat_mapping = list(cat.cat.categories)
|
1115 |
+
df_heatmap[selected_feature] = cat.cat.codes
|
1116 |
+
heat_stat, x_edges, y_edges, binnumber = binned_statistic_2d(
|
1117 |
+
df_heatmap['x'], df_heatmap['y'], df_heatmap[selected_feature],
|
1118 |
+
statistic='mean', bins=[x_bins, y_bins]
|
1119 |
+
)
|
1120 |
|
1121 |
+
# La función image de Bokeh espera una lista de arrays; se transpone para alinear los ejes.
|
1122 |
+
heatmap_data = heat_stat.T
|
1123 |
|
1124 |
# Crear el mapa de color
|
1125 |
color_mapper = LinearColorMapper(palette="Viridis256", low=np.nanmin(heatmap_data), high=np.nanmax(heatmap_data))
|
1126 |
|
1127 |
+
# Crear la figura para el heatmap con fondo blanco
|
1128 |
heatmap_fig = figure(title=f"Heatmap de '{selected_feature}'",
|
1129 |
x_range=(x_min, x_max), y_range=(y_min, y_max),
|
1130 |
width=600, height=600,
|
1131 |
tools="pan,wheel_zoom,reset,save", active_scroll="wheel_zoom")
|
1132 |
+
heatmap_fig.background_fill_color = "white"
|
1133 |
|
1134 |
+
# Dibujar el heatmap usando la imagen
|
1135 |
heatmap_fig.image(image=[heatmap_data], x=x_min, y=y_min,
|
1136 |
dw=x_max - x_min, dh=y_max - y_min,
|
1137 |
color_mapper=color_mapper)
|
1138 |
|
1139 |
+
# Crear la barra de colores
|
1140 |
color_bar = ColorBar(color_mapper=color_mapper, location=(0, 0))
|
1141 |
+
# Si se usó conversión a categoría, formateamos la barra para mostrar las etiquetas originales
|
1142 |
+
if cat_mapping is not None:
|
1143 |
+
|
1144 |
+
categories_json = json.dumps(cat_mapping)
|
1145 |
+
color_bar.formatter = FuncTickFormatter(code=f"""
|
1146 |
+
var categories = {categories_json};
|
1147 |
+
var index = Math.round(tick);
|
1148 |
+
if(index >= 0 && index < categories.length) {{
|
1149 |
+
return categories[index];
|
1150 |
+
}} else {{
|
1151 |
+
return "";
|
1152 |
+
}}
|
1153 |
+
""")
|
1154 |
heatmap_fig.add_layout(color_bar, 'right')
|
1155 |
|
1156 |
st.bokeh_chart(heatmap_fig)
|