AIdeaText commited on
Commit
e8e90cf
·
verified ·
1 Parent(s): 0ea8667

Update modules/discourse/discourse_interface.py

Browse files
Files changed (1) hide show
  1. modules/discourse/discourse_interface.py +124 -163
modules/discourse/discourse_interface.py CHANGED
@@ -130,189 +130,150 @@ def display_discourse_interface(lang_code, nlp_models, discourse_t):
130
 
131
 
132
  #####################################################################################################################
 
133
  def display_discourse_results(result, lang_code, discourse_t):
134
  """
135
  Muestra los resultados del análisis del discurso
 
 
 
 
 
136
  """
137
  if not result.get('success'):
138
  st.warning(discourse_t.get('no_results', 'No hay resultados disponibles'))
139
  return
140
 
141
- # Estilo CSS
142
  st.markdown("""
143
- <style>
144
- .concepts-container {
145
- display: flex;
146
- flex-wrap: nowrap;
147
- gap: 8px;
148
- padding: 12px;
149
- background-color: #f8f9fa;
150
- border-radius: 8px;
151
- overflow-x: auto;
152
- margin-bottom: 15px;
153
- white-space: nowrap;
154
- }
155
- .concept-item {
156
- background-color: white;
157
- border-radius: 4px;
158
- padding: 6px 10px;
159
- display: inline-flex;
160
- align-items: center;
161
- gap: 4px;
162
- box-shadow: 0 1px 2px rgba(0,0,0,0.1);
163
- flex-shrink: 0;
164
- }
165
- .concept-name {
166
- font-weight: 500;
167
- color: #1f2937;
168
- font-size: 0.85em;
169
- }
170
- .concept-freq {
171
- color: #6b7280;
172
- font-size: 0.75em;
173
- }
174
- .graph-container {
175
- background-color: white;
176
- padding: 15px;
177
- border-radius: 8px;
178
- box-shadow: 0 2px 4px rgba(0,0,0,0.1);
179
- margin-top: 10px;
180
- }
181
- </style>
182
  """, unsafe_allow_html=True)
183
 
 
184
  col1, col2 = st.columns(2)
185
-
186
  # Documento 1
187
  with col1:
188
  st.subheader(discourse_t.get('compare_doc1_title', 'Documento 1'))
189
- st.markdown(discourse_t.get('key_concepts', 'Conceptos Clave'))
190
  if 'key_concepts1' in result:
191
- concepts_html = f"""
192
- <div class="concepts-container">
193
- {''.join([
194
- f'<div class="concept-item"><span class="concept-name">{concept}</span>'
195
- f'<span class="concept-freq">({freq:.2f})</span></div>'
196
- for concept, freq in result['key_concepts1']
197
- ])}
198
- </div>
199
- """
200
- st.markdown(concepts_html, unsafe_allow_html=True)
201
-
202
- # Verificar el tipo de graph1 de manera más robusta
203
- if 'graph1' in result:
204
- st.markdown('<div class="graph-container">', unsafe_allow_html=True)
205
-
206
- # Más información para depuración
207
- graph_type = type(result['graph1']).__name__
208
- graph_size = len(result['graph1']) if isinstance(result['graph1'], bytes) else "N/A"
209
- logger.info(f"Tipo de graph1: {graph_type}, Tamaño: {graph_size}")
210
-
211
- if isinstance(result['graph1'], bytes) and len(result['graph1']) > 0:
212
- # Es bytes válidos
213
- st.image(result['graph1'])
214
- elif isinstance(result['graph1'], plt.Figure):
215
- # Es una figura de matplotlib
216
- st.pyplot(result['graph1'])
217
- elif result['graph1'] is None:
218
- # Es None
219
- st.warning("Gráfico no disponible")
220
- else:
221
- # Otro tipo o bytes vacíos
222
- st.warning(f"Formato de gráfico no reconocido: {graph_type}")
223
-
224
- # Botones y controles
225
- button_col1, spacer_col1 = st.columns([1,4])
226
- with button_col1:
227
- if 'graph1_bytes' in result:
228
- st.download_button(
229
- label="📥 " + discourse_t.get('download_graph', "Download"),
230
- data=result['graph1_bytes'],
231
- file_name="discourse_graph1.png",
232
- mime="image/png",
233
- use_container_width=True
234
- )
235
-
236
- # Interpretación como texto normal sin expander
237
- st.markdown("**📊 Interpretación del grafo:**")
238
- st.markdown("""
239
- - 🔀 Las flechas indican la dirección de la relación entre conceptos
240
- - 🎨 Los colores más intensos indican conceptos más centrales en el texto
241
- - ⭕ El tamaño de los nodos representa la frecuencia del concepto
242
- - ↔️ El grosor de las líneas indica la fuerza de la conexión
243
- """)
244
-
245
- st.markdown('</div>', unsafe_allow_html=True)
246
- else:
247
- st.warning(discourse_t.get('graph_not_available', 'Gráfico no disponible'))
248
- else:
249
- st.warning(discourse_t.get('concepts_not_available', 'Conceptos no disponibles'))
250
 
251
  # Documento 2
252
  with col2:
253
  st.subheader(discourse_t.get('compare_doc2_title', 'Documento 2'))
254
- st.markdown(discourse_t.get('key_concepts', 'Conceptos Clave'))
255
  if 'key_concepts2' in result:
256
- concepts_html = f"""
257
- <div class="concepts-container">
258
- {''.join([
259
- f'<div class="concept-item"><span class="concept-name">{concept}</span>'
260
- f'<span class="concept-freq">({freq:.2f})</span></div>'
261
- for concept, freq in result['key_concepts2']
262
- ])}
263
- </div>
264
- """
265
- st.markdown(concepts_html, unsafe_allow_html=True)
266
-
267
- # Verificar el tipo de graph1 de manera más robusta
268
- if 'graph1' in result:
269
- st.markdown('<div class="graph-container">', unsafe_allow_html=True)
270
-
271
- # Más información para depuración
272
- graph_type = type(result['graph2']).__name__
273
- graph_size = len(result['graph2']) if isinstance(result['graph2'], bytes) else "N/A"
274
- logger.info(f"Tipo de graph2: {graph_type}, Tamaño: {graph_size}")
275
-
276
- if isinstance(result['graph2'], bytes) and len(result['graph2']) > 0:
277
- # Es bytes válidos
278
- st.image(result['graph2'])
279
- elif isinstance(result['graph2'], plt.Figure):
280
- # Es una figura de matplotlib
281
- st.pyplot(result['graph2'])
282
- elif result['graph2'] is None:
283
- # Es None
284
- st.warning("Gráfico no disponible")
285
- else:
286
- # Otro tipo o bytes vacíos
287
- st.warning(f"Formato de gráfico no reconocido: {graph_type}")
288
-
289
- # Botones y controles
290
- button_col2, spacer_col2 = st.columns([1,4])
291
- with button_col2:
292
- if 'graph2_bytes' in result:
293
- st.download_button(
294
- label="📥 " + discourse_t.get('download_graph', "Download"),
295
- data=result['graph2_bytes'],
296
- file_name="discourse_graph2.png",
297
- mime="image/png",
298
- use_container_width=True
299
- )
300
 
301
- # Interpretación como texto normal sin expander
302
- st.markdown("**📊 Interpretación del grafo:**")
303
- st.markdown("""
304
- - 🔀 Las flechas indican la dirección de la relación entre conceptos
305
- - 🎨 Los colores más intensos indican conceptos más centrales en el texto
306
- - ⭕ El tamaño de los nodos representa la frecuencia del concepto
307
- - ↔️ El grosor de las líneas indica la fuerza de la conexión
308
- """)
309
-
310
- st.markdown('</div>', unsafe_allow_html=True)
311
- else:
312
- st.warning(discourse_t.get('graph_not_available', 'Gráfico no disponible'))
313
- else:
314
- st.warning(discourse_t.get('concepts_not_available', 'Conceptos no disponibles'))
 
 
 
315
 
316
- # Nota informativa sobre la comparación
317
- st.info(discourse_t.get('comparison_note',
318
- 'La funcionalidad de comparación detallada estará disponible en una próxima actualización.'))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
 
131
 
132
  #####################################################################################################################
133
+
134
  def display_discourse_results(result, lang_code, discourse_t):
135
  """
136
  Muestra los resultados del análisis del discurso
137
+ Versión actualizada con:
138
+ - Un solo expander para interpretación
139
+ - Botón de descarga combinado
140
+ - Sin mensaje de "próxima actualización"
141
+ - Estilo consistente con semantic_interface
142
  """
143
  if not result.get('success'):
144
  st.warning(discourse_t.get('no_results', 'No hay resultados disponibles'))
145
  return
146
 
147
+ # Estilo CSS unificado
148
  st.markdown("""
149
+ <style>
150
+ .concept-table {
151
+ display: flex;
152
+ flex-wrap: wrap;
153
+ gap: 10px;
154
+ margin-bottom: 20px;
155
+ }
156
+ .concept-item {
157
+ background-color: #f0f2f6;
158
+ border-radius: 5px;
159
+ padding: 8px 12px;
160
+ display: flex;
161
+ align-items: center;
162
+ gap: 8px;
163
+ }
164
+ .concept-name {
165
+ font-weight: bold;
166
+ }
167
+ .concept-freq {
168
+ color: #666;
169
+ font-size: 0.9em;
170
+ }
171
+ .download-btn-container {
172
+ display: flex;
173
+ justify-content: center;
174
+ margin-top: 15px;
175
+ }
176
+ </style>
 
 
 
 
 
 
 
 
 
 
 
177
  """, unsafe_allow_html=True)
178
 
179
+ # Mostrar conceptos clave para ambos documentos
180
  col1, col2 = st.columns(2)
181
+
182
  # Documento 1
183
  with col1:
184
  st.subheader(discourse_t.get('compare_doc1_title', 'Documento 1'))
 
185
  if 'key_concepts1' in result:
186
+ df1 = pd.DataFrame(
187
+ result['key_concepts1'],
188
+ columns=[discourse_t.get('concept', 'Concepto'), discourse_t.get('frequency', 'Frecuencia')]
189
+ )
190
+ st.write(
191
+ '<div class="concept-table">' +
192
+ ''.join([
193
+ f'<div class="concept-item"><span class="concept-name">{concept}</span>'
194
+ f'<span class="concept-freq">({freq:.2f})</span></div>'
195
+ for concept, freq in df1.values
196
+ ]) + "</div>",
197
+ unsafe_allow_html=True
198
+ )
199
+
200
+ if 'graph1' in result and result['graph1']:
201
+ st.image(result['graph1'], use_container_width=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202
 
203
  # Documento 2
204
  with col2:
205
  st.subheader(discourse_t.get('compare_doc2_title', 'Documento 2'))
 
206
  if 'key_concepts2' in result:
207
+ df2 = pd.DataFrame(
208
+ result['key_concepts2'],
209
+ columns=[discourse_t.get('concept', 'Concepto'), discourse_t.get('frequency', 'Frecuencia')]
210
+ )
211
+ st.write(
212
+ '<div class="concept-table">' +
213
+ ''.join([
214
+ f'<div class="concept-item"><span class="concept-name">{concept}</span>'
215
+ f'<span class="concept-freq">({freq:.2f})</span></div>'
216
+ for concept, freq in df2.values
217
+ ]) + "</div>",
218
+ unsafe_allow_html=True
219
+ )
220
+
221
+ if 'graph2' in result and result['graph2']:
222
+ st.image(result['graph2'], use_container_width=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
 
224
+ # Sección unificada de interpretación (como semantic_interface)
225
+ st.markdown("""
226
+ <style>
227
+ div[data-testid="stExpander"] div[role="button"] p {
228
+ text-align: center;
229
+ font-weight: bold;
230
+ }
231
+ </style>
232
+ """, unsafe_allow_html=True)
233
+
234
+ with st.expander("📊 " + discourse_t.get('semantic_graph_interpretation', "Interpretación de los gráficos")):
235
+ st.markdown(f"""
236
+ - 🔀 {discourse_t.get('compare_arrow_meaning', 'Las flechas indican la dirección de la relación entre conceptos')}
237
+ - 🎨 {discourse_t.get('compare_color_meaning', 'Los colores más intensos indican conceptos más centrales en el texto')}
238
+ - ⭕ {discourse_t.get('compare_size_meaning', 'El tamaño de los nodos representa la frecuencia del concepto')}
239
+ - ↔️ {discourse_t.get('compare_thickness_meaning', 'El grosor de las líneas indica la fuerza de la conexión')}
240
+ """)
241
 
242
+ # Botón de descarga combinado (para ambas imágenes)
243
+ if 'graph1' in result and 'graph2' in result and result['graph1'] and result['graph2']:
244
+ # Crear figura combinada
245
+ fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(24, 10))
246
+
247
+ # Mostrar primer gráfico
248
+ if isinstance(result['graph1'], bytes):
249
+ img1 = plt.imread(io.BytesIO(result['graph1']))
250
+ ax1.imshow(img1)
251
+ ax1.axis('off')
252
+ ax1.set_title(discourse_t.get('compare_doc1_title', 'Documento 1'))
253
+
254
+ # Mostrar segundo gráfico
255
+ if isinstance(result['graph2'], bytes):
256
+ img2 = plt.imread(io.BytesIO(result['graph2']))
257
+ ax2.imshow(img2)
258
+ ax2.axis('off')
259
+ ax2.set_title(discourse_t.get('compare_doc2_title', 'Documento 2'))
260
+
261
+ plt.tight_layout()
262
+
263
+ # Convertir a bytes
264
+ buf = io.BytesIO()
265
+ plt.savefig(buf, format='png', dpi=150, bbox_inches='tight')
266
+ buf.seek(0)
267
+
268
+ # Botón de descarga
269
+ st.markdown('<div class="download-btn-container">', unsafe_allow_html=True)
270
+ st.download_button(
271
+ label="📥 " + discourse_t.get('download_both_graphs', "Descargar ambos gráficos"),
272
+ data=buf,
273
+ file_name="comparison_graphs.png",
274
+ mime="image/png",
275
+ use_container_width=True
276
+ )
277
+ st.markdown('</div>', unsafe_allow_html=True)
278
+
279
+ plt.close()