tx3bas commited on
Commit
f92e2b1
·
verified ·
1 Parent(s): 9480117

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +184 -0
app.py CHANGED
@@ -91,6 +91,190 @@ else:
91
  # Procesar valores
92
  y_values_lists = [[float(i) for i in y_values.split(",") if i.strip()] for y_values in y_values_list]
93
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  # Verificar si las listas tienen el mismo tamaño
95
  if any(len(x) != len(y) for y in y_values_lists):
96
  st.error("Todos los valores de X y Y deben tener la misma cantidad de elementos.")
 
91
  # Procesar valores
92
  y_values_lists = [[float(i) for i in y_values.split(",") if i.strip()] for y_values in y_values_list]
93
 
94
+ # Verificar si las listas tienen el mismo tamaño
95
+ if any(len(x) != len(y) for y in y_values_lists):
96
+ st.error("Todos los valores de X y Y deben tener la misma cantidad de elementos.")
97
+ else:
98
+ # Crear un DataFrame
99
+ data = pd.DataFrame({"X": x})
100
+ for idx, y_set in enumerate(y_values_lists):
101
+ data[y_names_list[idx]] = y_set
102
+
103
+ # Configuración común para todos los gráficos
104
+ common_layout = dict(
105
+ xaxis_title=x_label,
106
+ yaxis_title=y_label,
107
+ plot_bgcolor="white",
108
+ hovermode="x unified",
109
+ width=graph_width,
110
+ height=graph_height,
111
+ margin=dict(l=60, r=40, t=100, b=40),
112
+ xaxis=dict(showgrid=True, zeroline=True, gridcolor='rgba(211,211,211,0.5)', zerolinecolor='rgba(128,128,128,0.5)', autorange=True),
113
+ yaxis=dict(showgrid=True, zeroline=True, gridcolor='rgba(211,211,211,0.5)', zerolinecolor='rgba(128,128,128,0.5)', autorange=True),
114
+ font=dict(family=font_family, size=18, color="black"),
115
+ showlegend=show_legend,
116
+ legend=dict(orientation="v", yanchor="top", y=1, xanchor="left", x=1.02)
117
+ )
118
+
119
+ # Personalizar el hovertemplate
120
+ hovertemplate = '<b>%{y}</b>'
121
+
122
+ # Generar el gráfico basado en el tipo seleccionado
123
+ if chart_type == "Línea":
124
+ fig = px.line(data, x="X", y=y_names_list, line_shape="spline")
125
+ fig.update_traces(hovertemplate=hovertemplate)
126
+ if use_multiple_colors:
127
+ for i, name in enumerate(y_names_list):
128
+ fig.update_traces(selector=dict(name=name), line_color=colors[i % len(colors)])
129
+ else:
130
+ fig.update_traces(line_color=color)
131
+ elif chart_type == "Área":
132
+ fig = px.area(data, x="X", y=y_names_list, line_shape="spline")
133
+ fig.update_traces(hovertemplate=hovertemplate)
134
+ if use_multiple_colors:
135
+ for i, name in enumerate(y_names_list):
136
+ fig.update_traces(selector=dict(name=name), line_color=colors[i % len(colors)], fillcolor=colors[i % len(colors)])
137
+ else:
138
+ fig.update_traces(line_color=color, fillcolor=color)
139
+ elif chart_type == "Dispersión":
140
+ fig = px.scatter(data, x="X", y=y_names_list)
141
+ fig.update_traces(hovertemplate=hovertemplate)
142
+ if use_multiple_colors:
143
+ for i, name in enumerate(y_names_list):
144
+ fig.update_traces(selector=dict(name=name), marker_color=colors[i % len(colors)], marker_line_color=border_colors[i % len(border_colors)], marker_line_width=border_width)
145
+ else:
146
+ fig.update_traces(marker_color=color, marker_line_color=border_color, marker_line_width=border_width)
147
+ elif chart_type == "Barras":
148
+ if horizontal_bars:
149
+ fig = px.bar(data, x=y_names_list[0], y="X", orientation='h', barmode='stack' if stacked_bars else 'group')
150
+ else:
151
+ fig = px.bar(data, x="X", y=y_names_list, barmode='stack' if stacked_bars else 'group')
152
+ fig.update_traces(hovertemplate=hovertemplate)
153
+ if use_multiple_colors:
154
+ for i in range(len(data)):
155
+ fig.data[i].marker.color = colors[i % len(colors)]
156
+ fig.data[i].marker.line.color = border_colors[i % len(border_colors)]
157
+ fig.data[i].marker.line.width = border_width
158
+ else:
159
+ fig.update_traces(marker_color=color, marker_line_color=border_color, marker_line_width=border_width)
160
+ fig.update_layout(bargap=0.2)
161
+ elif chart_type == "Donut":
162
+ figs = []
163
+ for i, y_name in enumerate(y_names_list):
164
+ fig = px.pie(data, values=y_name, names="X", hole=hole_size, color_discrete_sequence=colors[:len(x)])
165
+ fig.update_traces(hovertemplate='<b>%{label}</b>: %{value} (%{percent})', textinfo='percent+label')
166
+ fig.update_layout(
167
+ title=dict(
168
+ text=f"{chart_title}<br><sub>{y_name}</sub>" if len(y_names_list) > 1 else chart_title,
169
+ x=0.5,
170
+ y=0.95,
171
+ xanchor='center',
172
+ yanchor='top',
173
+ font=dict(
174
+ family=font_family,
175
+ size=18,
176
+ color="#374151",
177
+ weight="normal"
178
+ )
179
+ ),
180
+ **common_layout
181
+ )
182
+ figs.append(fig)
183
+ for fig in figs:
184
+ st.plotly_chart(fig)
185
+
186
+ # Añadir anotación para el título
187
+ if chart_type != "Donut":
188
+ fig.update_layout(
189
+ title=dict(
190
+ text=f"{chart_title}",
191
+ x=0.5,
192
+ y=0.95,
193
+ xanchor='center',
194
+ yanchor='top',
195
+ font=dict(
196
+ family=font_family,
197
+ size=18,
198
+ color="#374151",
199
+ weight="normal"
200
+ )
201
+ )
202
+ )
203
+
204
+ # Aplicar configuración común
205
+ fig.update_layout(**common_layout)
206
+
207
+ # Aplicar múltiples colores si se seleccionó la opción
208
+ if use_multiple_colors and chart_type != "Donut":
209
+ for i, trace in enumerate(fig.data):
210
+ trace.update(marker_color=colors[i % len(colors)], marker_line_color=border_colors[i % len(border_colors)], marker_line_width=border_width)
211
+
212
+ # Mostrar el gráfico
213
+ st.plotly_chart(fig)
214
+
215
+ # Forzar el autoescale
216
+ fig.update_layout(xaxis_autorange=True, yaxis_autorange=True)
217
+
218
+ # Información adicional
219
+ st.write("""
220
+ """)
221
+
222
+ # Selector de número de variables Y
223
+ num_y_vars = st.sidebar.number_input("Número de variables Y", min_value=1, max_value=100, value=1, step=1)
224
+ y_values_list = []
225
+ y_names_list = []
226
+ for i in range(num_y_vars):
227
+ if f"y_values_{i}" not in st.session_state:
228
+ st.session_state[f"y_values_{i}"] = ','.join([str(np.random.randint(1, 25)) for _ in x])
229
+ y_values = st.sidebar.text_area(f"Valores para Y-{i+1} (separados por comas)", st.session_state[f"y_values_{i}"])
230
+ st.session_state[f"y_values_{i}"] = y_values # Guardar los valores en session_state
231
+ y_name = st.sidebar.text_input(f"Nombre de la Variable Y-{i+1}", f"Variable Y-{i+1}")
232
+ y_values_list.append(y_values)
233
+ y_names_list.append(y_name)
234
+
235
+ # Etiquetas personalizadas para los ejes
236
+ x_label = st.sidebar.text_input("Etiqueta para el eje X", "X")
237
+ y_label = st.sidebar.text_input("Etiqueta para el eje Y", "Y")
238
+
239
+ # Desplegable de opciones adicionales
240
+ with st.sidebar.expander("Opciones Adicionales"):
241
+ graph_width = st.slider("Ancho del Gráfico", min_value=400, max_value=1000, value=800, step=50)
242
+ graph_height = st.slider("Alto del Gráfico", min_value=300, max_value=800, value=600, step=50)
243
+ font_family = st.selectbox("Fuente", font_options, index=font_options.index("Times New Roman"))
244
+ show_legend = st.checkbox("Mostrar Leyenda", value=True)
245
+ opacity = st.slider("Opacidad (%)", min_value=0, max_value=100, value=30, step=1) / 100
246
+ border_width = st.slider("Grosor del Borde", min_value=0.0, max_value=3.0, value=1.5, step=0.1)
247
+ border_opacity = st.slider("Opacidad del Borde (%)", min_value=0, max_value=100, value=60, step=1) / 100
248
+ if chart_type == "Barras" and num_y_vars > 1:
249
+ stacked_bars = st.checkbox("Superpuestas")
250
+ else:
251
+ stacked_bars = False
252
+ if chart_type == "Barras":
253
+ horizontal_bars = st.checkbox("Invertidas")
254
+ if chart_type == "Donut":
255
+ hole_size = st.slider("Tamaño del agujero (%)", min_value=0, max_value=100, value=30, step=1) / 100
256
+
257
+ # Opción para múltiples colores (siempre activada para Donut)
258
+ use_multiple_colors = st.sidebar.checkbox("Usar múltiples colores", value=True if chart_type == "Donut" or num_y_vars > 1 else False)
259
+
260
+ # Seleccionar color(es) para el gráfico
261
+ selected_color = st.sidebar.color_picker("Color", "#24CBA0", key="single_color")
262
+
263
+ # Definir colores
264
+ if use_multiple_colors or chart_type == "Donut":
265
+ num_colors = max(len(y_values_list), len(x))
266
+ colors = [hex_to_rgba(selected_color if i == 0 else st.sidebar.color_picker(f"Color {i+1}", predefined_colors[i % len(predefined_colors)], key=f"color_{i}"), alpha=opacity)
267
+ for i in range(num_colors)]
268
+ border_colors = [hex_to_rgba(selected_color if i == 0 else predefined_colors[i % len(predefined_colors)], alpha=border_opacity)
269
+ for i in range(num_colors)]
270
+ else:
271
+ color = hex_to_rgba(selected_color, alpha=opacity)
272
+ border_color = hex_to_rgba(selected_color, alpha=border_opacity)
273
+ colors = [color] * len(x) # Definir colors para casos donde no se usa múltiple colores
274
+
275
+ # Procesar valores
276
+ y_values_lists = [[float(i) for i in y_values.split(",") if i.strip()] for y_values in y_values_list]
277
+
278
  # Verificar si las listas tienen el mismo tamaño
279
  if any(len(x) != len(y) for y in y_values_lists):
280
  st.error("Todos los valores de X y Y deben tener la misma cantidad de elementos.")