Módulo: graficador.py
#
Este es el módulo que se encarga de hacer la visualización de los datos, es uno de los módulos más complejos y por tanto tiene demasiados métodos incluidos en él.
- src.graficador.centrar_ventana(ventana_principal, ventana_emergente)#
def centrar_ventana(ventana_principal, ventana_emergente): raiz.update_idletasks() # Obtener dimensiones y posición de la ventana principal ancho_principal = raiz.winfo_width() alto_principal = raiz.winfo_height() pos_x_principal = raiz.winfo_x() pos_y_principal = raiz.winfo_y() # Obtener dimensiones de la ventana emergente ancho_emergente = ventana_emergente.winfo_width() alto_emergente = ventana_emergente.winfo_height() # Calcular posición centrada con respecto a la ventana principal x_centrado = pos_x_principal + (ancho_principal - ancho_emergente) // 2 y_centrado = pos_y_principal + (alto_principal - alto_emergente) // 2 # Establecer geometría centrada ventana_emergente.geometry(f"{ancho_emergente}x{alto_emergente}+{x_centrado}+{y_centrado}")
- src.graficador.limpiar_grafica()#
Limpia la gráfica actual y restablece sus parámetros a los valores predeterminados.
Esta función restablece todas las configuraciones visuales de la gráfica, como el título, los colores, los estilos y los tamaños de los ejes. También se desactiva la cuadrícula si está activada y se reinician los límites de los ejes. La gráfica se redibuja con estos valores predeterminados.
Además, se restaura el estado de las variables globales que controlan las configuraciones visuales y otros parámetros gráficos.
Variables globales:#
- x_limitslist
Lista con los límites actuales del eje “x” en la forma [xmin, xmax].
- y_limitslist
Lista con los límites actuales del eje “y” en la forma [ymin, ymax].
- marker_colorstr
Color predeterminado del marcador en la gráfica.
- marker_typestr
Tipo de marcador utilizado para los puntos en la gráfica.
- show_gridbool
Indicador de si la cuadrícula de la gráfica está activada.
- point_sizeint
Tamaño de los puntos de marcador en la gráfica.
- titulo_graficatkinter.StringVar
Título de la gráfica como variable de texto.
- title_fuentestr
Tipo de fuente para el título de la gráfica.
- title_sizeint
Tamaño de la fuente para el título de la gráfica.
- ejex_shapestr
Tipo de fuente del título del eje “x”.
- ejex_sizeint
Tamaño de la fuente del título del eje “x”.
- ejex_titulotkinter.StringVar
Título del eje “x” como variable de texto.
- ejey_shapestr
Tipo de fuente del título del eje “y”.
- ejey_sizeint
Tamaño de la fuente del título del eje “y”.
- ejey_titulotkinter.StringVar
Título del eje “y” como variable de texto.
- line_colorstr
Color de la línea de la gráfica.
- line_widthint
Grosor de la línea de la gráfica.
- bg_colorstr
Color de fondo de la gráfica.
Retorna:#
None: La función no retorna valor, modifica directamente la configuración visual de la gráfica.
Uso:#
Esta función es útil para restablecer los parámetros de la gráfica a sus valores predeterminados, permitiendo una visualización limpia y estándar antes de realizar nuevas representaciones gráficas.
def limpiar_grafica(): global y_limits, x_limits, origx_lim, origy_lim, marker_color, marker_type, show_grid, point_size, titulo_grafica, title_fuente, title_size, ejex_shape, ejex_size, ejex_titulo, ejey_shape, ejey_size, ejey_titulo, line_color, line_width, bg_color, regresiones titulo_grafica = StringVar(value="Título de la Gráfica") title_fuente = "DejaVu Sans" title_size = 12 ejex_titulo = StringVar(value="") ejex_shape = "DejaVu Sans" ejex_size = 10 ejey_titulo = StringVar(value="") ejey_shape = "DejaVu Sans" ejey_size = 10 line_color = 'blue' line_width = 2 bg_color = "white" marker_type = "o" marker_color = "blue" show_grid = False point_size = 5 zoom(reset=True) regresiones.clear() # Vaciar la lista de regresiones ax.clear() x_limits = None y_limits = None origx_lim = None origy_lim = None ax.grid(show_grid) ax.set_facecolor(bg_color) canvas.draw() limpio_si()
- src.graficador.confirmar_limpiar_grafica()#
Muestra una ventana emergente de confirmación para limpiar la gráfica.
Esta función crea una ventana emergente que pregunta al usuario si desea limpiar la gráfica actual. Ofrece dos opciones: «Sí, limpiar» y «No, Cancelar». Si el usuario elige «Sí, limpiar», se llama a la función limpiar_grafica y se cierra la ventana de confirmación. Si el usuario elige «No, Cancelar», la ventana se cierra sin modificar la gráfica.
La ventana de confirmación se centra con respecto a la ventana principal y es modal, lo que significa que bloquea la interacción con otras ventanas de la aplicación hasta que se tome una decisión.
Variables globales:#
- raiztkinter.Tk
Ventana principal de la interfaz gráfica, sobre la cual se despliega la ventana de confirmación.
Retorna:#
None: La función no retorna ningún valor. Solo muestra una ventana de confirmación y actúa en función de la respuesta del usuario.
Uso:#
Esta función es útil cuando se desea solicitar una confirmación al usuario antes de realizar una acción que modifique la visualización de la gráfica.
def confirmar_limpiar_grafica(): ventana_confirmacion = Toplevel(raiz) ventana_confirmacion.title("Confirmación de limpieza") mensaje = Label(ventana_confirmacion, text="¿Está seguro que desea limpiar la gráfica?") mensaje.pack(pady=10) boton_si = Button(ventana_confirmacion, text="Sí, limpiar", command=lambda: [limpiar_grafica(), ventana_confirmacion.destroy()]) boton_si.pack(side="left", padx=10, pady=10) boton_no = Button(ventana_confirmacion, text="No, Cancelar", command=ventana_confirmacion.destroy) boton_no.pack(side="right", padx=10, pady=10) # Actualizar para obtener las dimensiones de la ventana emergente ventana_confirmacion.update_idletasks() centrar_ventana(raiz, ventana_confirmacion) # Hacer que la ventana emergente sea modal ventana_confirmacion.transient(raiz) ventana_confirmacion.grab_set()
- src.graficador.limpio_si()#
Muestra una ventana emergente de confirmación indicando que la gráfica ha sido limpiada exitosamente.
Esta función crea una ventana emergente que informa al usuario que la gráfica ha sido limpiada correctamente. Incluye un mensaje de éxito y un botón de «Aceptar» que cierra la ventana emergente cuando se presiona.
La ventana emergente se centra con respecto a la ventana principal y es modal, lo que impide la interacción con otras partes de la aplicación hasta que se cierre la ventana de confirmación.
Variables globales:#
- raiztkinter.Tk
Ventana principal de la interfaz gráfica, sobre la cual se despliega la ventana de confirmación.
Retorna:#
None: La función no retorna ningún valor. Solo muestra una ventana de confirmación de éxito.
Uso:#
Esta función es útil para notificar al usuario que la acción de limpieza de la gráfica se ha realizado con éxito.
def limpio_si(): ventana_hecho = Toplevel(raiz) ventana_hecho.title("Éxito") Label(ventana_hecho, text="La gráfica ha sido limpiada.", pady=20).pack() Button(ventana_hecho, text="Aceptar", command=ventana_hecho.destroy).pack(pady=10) # Actualizar para obtener las dimensiones de la ventana emergente ventana_hecho.update_idletasks() centrar_ventana(raiz, ventana_hecho) # Hacer que la ventana emergente sea modal ventana_hecho.transient(raiz) ventana_hecho.grab_set()
- src.graficador.cargar_datos()#
Carga los datos desde un archivo temporal llamado “tmp_graph.pkl” al iniciar la aplicación. Si el archivo existe, los datos se cargan en la variable global data. Si no existe, muestra un mensaje de advertencia.
Almacena los datos en la variable global data para ser utilizados en toda la aplicación.
def cargar_datos(): global data if os.path.exists("tmp_graph.pkl"): try: # Cargar archivo temporal .pkl en un DataFrame with open("tmp_graph.pkl", 'rb') as f: data = pickle.load(f) if not data.empty: actualizar_columnas() # Actualizar opciones de columnas else: messagebox.showerror("Error", "El archivo 'tmp_graph.pkl' está vacío.") except Exception as e: messagebox.showerror("Error", f"No se pudieron cargar los datos: {e}") else: messagebox.showwarning("Advertencia", "No se encontró el archivo 'tmp_graph.pkl'.")
- src.graficador.actualizar_columnas()#
Obtiene los nombres de las columnas del archivo de datos cargado y actualiza los elementos de la interfaz para permitir la selección de columnas para graficar.
Esta función obtiene los nombres de las columnas del archivo de datos actualmente cargado en la variable global data. Luego, actualiza o crea los ComboBox para que el usuario pueda seleccionar las columnas para los ejes “X” e “Y”. Además, coloca un botón que permite iniciar la graficación de los datos seleccionados. Si no hay columnas disponibles, se muestra un mensaje de error indicando que no se pueden graficar los datos.
Variables globales:#
- columna_x_combottk.Combobox
Widget de tipo Combobox para la selección de la columna en el eje X.
- columna_y_combottk.Combobox
Widget de tipo Combobox para la selección de la columna en el eje Y.
- graficar_buttontkinter.Button
Botón para iniciar la acción de graficar los datos seleccionados.
- frame_columnastkinter.Frame
Frame en el que se colocan los widgets de selección de columnas y el botón de graficado.
Retorna:#
None: La función no retorna ningún valor. Solo actualiza los widgets de la interfaz gráfica.
Uso:#
Esta función es útil para permitir al usuario seleccionar las columnas que desea graficar y controlar el inicio de la graficación desde la interfaz.
def actualizar_columnas(): global columna_x_combo, columna_y_combo, graficar_button, frame_columnas # Eliminar widgets previos del frame for widget in frame_columnas.winfo_children(): widget.destroy() # Obtener las columnas del archivo de datos columns = data.columns.tolist() # Solo crear los ComboBox si hay columnas disponibles if columns: # ComboBox para columna X columna_x_combo = ttk.Combobox(frame_columnas, textvariable=columna_x, values=columns) columna_x_combo.grid(column=0, row=0, padx=5, pady=5) columna_x_combo.set("Selecciona la columna X") # ComboBox para columna Y columna_y_combo = ttk.Combobox(frame_columnas, textvariable=columna_y, values=columns) columna_y_combo.grid(column=1, row=0, padx=5, pady=5) columna_y_combo.set("Selecciona la columna Y") # Botón para graficar graficar_button = Button(frame_columnas, text="Graficar", command=graficar_datos) graficar_button.grid(column=3, row=0, columnspan=2, pady=10) else: messagebox.showerror("Error", "No se encontraron columnas para graficar.")
- src.graficador.guardar_grafica(formato)#
Muestra un cuadro de diálogo para seleccionar la ubicación y el nombre del archivo donde se guardará la gráfica actual, y la guarda en el formato especificado por el usuario.
Esta función permite al usuario elegir dónde guardar la gráfica generada en la aplicación, especificando el formato de archivo en el que desea guardarla. La gráfica se guarda utilizando la figura de matplotlib (fig) y el formato especificado. Si el usuario selecciona una ubicación y un nombre de archivo, la gráfica se guarda en ese archivo.
Parámetros#
- formatostr
El formato en el que se desea guardar la gráfica (por ejemplo, «png», «jpg», «pdf»).
Variables globales#
- figmatplotlib.figure.Figure
La figura de matplotlib que contiene la gráfica que se va a guardar.
Retorna#
None: La función no retorna ningún valor. Solo guarda la gráfica en el archivo especificado.
Uso#
Esta función es útil para guardar una copia de la gráfica generada en la aplicación en el formato deseado por el usuario.
def guardar_grafica(formato): archivo = filedialog.asksaveasfilename(defaultextension=f".{formato}", filetypes=[(f"{formato.upper()} files", f"*.{formato}"), ("All files", "*.*")]) if archivo: fig.savefig(archivo, format=formato) print(f"Gráfica guardada como {archivo}")
- src.graficador.graficar_datos()#
Dibuja o actualiza la gráfica de datos en el canvas de Matplotlib dentro de la interfaz gráfica. La función limpia la gráfica anterior, dibuja una nueva basada en los datos actuales y actualiza los títulos y límites de los ejes según las selecciones del usuario.
Esta función se encarga de graficar los datos seleccionados por el usuario para los ejes X e Y. Verifica que las columnas seleccionadas sean válidas y numéricas, luego crea una nueva gráfica con los datos correspondientes, ajustando los límites de los ejes y el formato de la gráfica según las configuraciones de la interfaz.
Variables globales#
- axmatplotlib.axes.Axes
El objeto de los ejes en los que se dibuja la gráfica.
- canvasFigureCanvasTkAgg
El widget de Matplotlib que renderiza la gráfica en la interfaz gráfica de usuario.
- xnumpy.ndarray
El arreglo de valores en el eje X que serán graficados.
- ynumpy.ndarray
El arreglo de valores en el eje Y que serán graficados.
- x_limitslist
Lista que contiene los límites actuales del eje “x” en la forma [xmin, xmax].
- y_limitslist
Lista que contiene los límites actuales del eje “y” en la forma [ymin, ymax].
- titulo_graficatkinter.StringVar
Variable que almacena el texto del título de la gráfica, el cual puede ser editado por el usuario.
- titulo_eje_xtkinter.StringVar
Variable que almacena el texto del título del eje X, editable por el usuario.
- titulo_eje_ytkinter.StringVar
Variable que almacena el texto del título del eje Y, editable por el usuario.
Retorna#
- None
No retorna ningún valor. Solo actualiza la gráfica en el canvas y los elementos de la interfaz.
Errores#
Muestra un mensaje de error si las columnas seleccionadas no son válidas o no son numéricas.
Uso#
Esta función se utiliza para graficar los datos seleccionados por el usuario desde el archivo cargado y ajustar los títulos y límites de los ejes en la gráfica.
def graficar_datos(): x_col = columna_x.get() y_col = columna_y.get() global origx_lim, origy_lim, x_limits, y_limits if x_col not in data.columns or y_col not in data.columns: messagebox.showerror("Error", "Una o ambas columnas seleccionadas no son válidas.") return if not pd.api.types.is_numeric_dtype(data[x_col]) or not pd.api.types.is_numeric_dtype(data[y_col]): messagebox.showerror("Error", "Las columnas seleccionadas deben ser numéricas.") return datos_x = data[x_col] datos_y = data[y_col] # Restablecer límites originales si es la primera vez que se grafican if origx_lim is None or origy_lim is None: origx_lim = [datos_x.min(), datos_x.max()] origy_lim = [datos_y.min(), datos_y.max()] x_limits = origx_lim.copy() y_limits = origy_lim.copy() # Restablecer límites automáticamente según los datos actuales x_limits = [datos_x.min(), datos_x.max()] y_limits = [datos_y.min(), datos_y.max()] # Actualizar títulos de los ejes con los nombres de las columnas seleccionadas ejex_titulo.set(x_col) ejey_titulo.set(y_col) ax.clear() x = data[x_col] # Usar la columna seleccionada para X y = data[y_col] # Usar la columna seleccionada para Y line, = ax.plot(x, y, color=line_color, marker=marker_type, markersize=point_size, markerfacecolor=marker_color, linewidth=line_width, label="Datos") ax.set_xlim(x_limits) # Límites del eje X ax.set_ylim(y_limits) # Límites del eje Y ax.set_title(titulo_grafica.get(), fontname=title_fuente, fontsize=title_size) # Actualizar título ax.set_xlabel(ejex_titulo.get(), fontname=ejex_shape, fontsize=ejex_size) # Actualizar título eje X ax.set_ylabel(ejey_titulo.get(), fontname=ejey_shape, fontsize=ejey_size) # Actualizar título eje Y ax.grid(show_grid) ax.set_facecolor(bg_color) # Se grafican las regresiones realizadas anteriormente if 'regresiones' in globals() and regresiones: for reg in regresiones: ax.plot( reg['x_vals'], reg['y_vals'], label=reg['label'], color=reg.get('color', 'blue'), linewidth=reg.get('line_width', 1.0), marker=reg.get('marker_type', 'o'), markersize=reg.get('point_size', 5), markerfacecolor=reg.get('marker_color', 'blue') ) ax.legend() canvas.draw() # Actualizar la gráfica # canvas.mpl_connect('button_press_event', on_double_click) # Crear botón "+" para edición de límites eje X x_plus_button = Button(raiz, text="+", command=lambda: update_x_limits(raiz)) x_plus_button.place(x=canvas.get_tk_widget().winfo_width() - 60, y=canvas.get_tk_widget().winfo_height() / 2 + 185) # Crear botón "+" para edición de límites eje Y y_plus_button = Button(raiz, text="+", command=lambda: update_y_limits(raiz)) y_plus_button.place(x=canvas.get_tk_widget().winfo_width() - 60, y=canvas.get_tk_widget().winfo_height() / 2 - 185)
- src.graficador.update_graph_property(property_type=None, new_value=None)#
Actualiza las propiedades visuales de la gráfica según el tipo de propiedad y el nuevo valor proporcionado. La función ajusta el estilo de la línea, el marcador, el color de fondo, el tamaño de los puntos, y la visibilidad de la cuadrícula, y actualiza la gráfica para reflejar los cambios.
Parámetros#
- property_typestr, opcional
El tipo de propiedad que se desea actualizar. Puede ser uno de los siguientes: - “line_width”: El grosor de la línea de la gráfica. - “marker_type”: El tipo de marcador utilizado en los puntos de la gráfica (ej. “o”, “s”, “x”). - “line_color”: El color de la línea de la gráfica. - “marker_color”: El color de los marcadores de la gráfica. - “bg_color”: El color de fondo del área de la gráfica. - “point_size”: El tamaño de los puntos o marcadores en la gráfica. - “grid”: Un valor booleano que indica si la cuadrícula debe ser visible o no.
- new_valuefloat, str o bool, opcional
El nuevo valor que se asignará a la propiedad seleccionada. Dependiendo de la propiedad, puede ser: - Un valor de tipo float (para grosor de línea o tamaño de punto), - Un valor de tipo str (para el tipo de marcador o color), - Un valor booleano (para la visibilidad de la cuadrícula).
Variables globales#
- line_widthfloat
Grosor de la línea de la gráfica.
- marker_typestr
Tipo de marcador que se utiliza en la gráfica.
- line_colorstr
Color de la línea de la gráfica.
- marker_colorstr
Color del marcador de la gráfica.
- bg_colorstr
Color de fondo del área de la gráfica.
- point_sizefloat
Tamaño de los puntos o marcadores en la gráfica.
- show_gridbool
Indica si la cuadrícula de la gráfica está visible o no.
- axmatplotlib.axes._axes.Axes
El objeto de ejes de matplotlib donde se configura el color de fondo y la cuadrícula.
- canvasmatplotlib.backends.backend_tkagg.FigureCanvasTkAgg
Canvas que contiene la gráfica y permite la actualización de eventos.
- linematplotlib.lines.Line2D
Línea de la gráfica que permite asociar eventos de clic.
def update_graph_property(property_type=None, new_value=None): global line_width, marker_type, line_color, marker_color, bg_color, point_size, show_grid if property_type == 'line_width': line_width = float(new_value) elif property_type == 'marker_type': marker_type = new_value elif property_type == 'line_color': line_color = colorchooser.askcolor()[1] elif property_type == 'marker_color': marker_color = colorchooser.askcolor()[1] elif property_type == 'bg_color': bg_color = colorchooser.askcolor()[1] ax.set_facecolor(bg_color) elif property_type == 'point_size': point_size = float(new_value) elif property_type == 'grid': show_grid = bool(new_value) ax.grid(show_grid) graficar_datos()
- src.graficador.grafica_ventana(master)#
Crea una ventana emergente para la personalización visual de la gráfica, permitiendo al usuario ajustar parámetros como el color de fondo, grosor de la línea, tipo de marcador, color y tamaño de puntos, y mostrar o ocultar la cuadrícula.
Parámetros#
- masterTkinter.Tk
Ventana principal de la aplicación.
Variables globales#
- personalizacion_ventanaTkinter.Toplevel
Referencia a la ventana emergente de personalización, para evitar crear múltiples instancias y poder acceder a sus elementos.
- show_gridbool
Valor booleano que indica si la cuadrícula de la gráfica está visible.
- line_widthfloat
Grosor actual de la línea de la gráfica.
- marker_typestr
Tipo de marcador utilizado en la gráfica.
- point_sizefloat
Tamaño actual de los puntos en la gráfica.
def grafica_ventana(master): global personalizacion_ventana if personalizacion_ventana is not None and personalizacion_ventana.winfo_exists(): personalizacion_ventana.lift() return personalizacion_ventana = Toplevel(master) personalizacion_ventana.title("Personalización de Gráfica") personalizacion_ventana.geometry("400x400") Label(personalizacion_ventana, text="Fondo", font=("Arial", 12, "bold")).pack(pady=10) Button(personalizacion_ventana, text="Color de Fondo", command=lambda: update_graph_property('bg_color')).pack(pady=5) grid_var = IntVar(value=int(show_grid)) # Inicializar con el valor actual Checkbutton(personalizacion_ventana, text="Mostrar Grilla", variable=grid_var, command=lambda: update_graph_property('grid', grid_var.get())).pack(pady=5) frame = Frame(personalizacion_ventana) frame.pack(pady=10) linea_frame = Frame(frame) linea_frame.grid(row=0, column=0, padx=20) Label(linea_frame, text="Línea", font=("Arial", 12, "bold")).pack(pady=10) Button(linea_frame, text="Color de Línea", command=lambda: update_graph_property('line_color')).pack(pady=5) Label(linea_frame, text="Tamaño de Línea:").pack(pady=5) line_width_slider = Scale(linea_frame, from_=0.5, to=10, resolution=0.1, orient=HORIZONTAL, command=lambda value: update_graph_property('line_width', value)) line_width_slider.set(line_width) line_width_slider.pack(pady=5) puntos_frame = Frame(frame) puntos_frame.grid(row=0, column=1, padx=20) Label(puntos_frame, text="Puntos", font=("Arial", 12, "bold")).pack(pady=10) Label(puntos_frame, text="Tipo de Marcador:").pack() marker_options = ['o', 'x', '^', 's', '*'] marker_var = StringVar(value=marker_type) marker_menu = ttk.Combobox(puntos_frame, textvariable=marker_var, values=marker_options) marker_menu.pack(pady=5) marker_menu.bind("<<ComboboxSelected>>", lambda event: update_graph_property('marker_type', marker_var.get())) Button(puntos_frame, text="Color de Puntos", command=lambda: update_graph_property('marker_color')).pack(pady=5) Label(puntos_frame, text="Tamaño de Puntos:").pack(pady=5) point_size_slider = Scale(puntos_frame, from_=1, to=20, resolution=1, orient=HORIZONTAL, command=lambda value: update_graph_property('point_size', value)) point_size_slider.set(point_size) point_size_slider.pack(pady=5) # Actualizar para obtener las dimensiones de la ventana emergente personalizacion_ventana.update_idletasks() centrar_ventana(raiz, personalizacion_ventana) # Hacer que la ventana emergente sea modal personalizacion_ventana.transient(raiz) personalizacion_ventana.grab_release()
- src.graficador.graficar_regresion(tipo)#
Grafica la regresión especificada según el tipo proporcionado para los datos cargados en la aplicación.
Parámetros:#
- tipostr
El tipo de regresión a realizar. Puede ser “lineal”, “polinomial” o “interpolacion”.
Funcionalidad:#
Esta función toma los nombres de las columnas x e y seleccionadas para realizar la regresión. Si no se han cargado datos, muestra un mensaje de error utilizando messagebox.showerror. Luego, crea una instancia de la clase RegressionAnalysis usando el conjunto de datos cargados (data).
Dependiendo del valor del argumento tipo, llama a la función correspondiente para calcular la regresión: - linear_regression para regresión lineal. - polynomial_regression para regresión polinómica. - interpolation para realizar una interpolación.
Los métodos de regresión devuelven los valores x_vals, y_vals y la ecuación de la línea ajustada. Los resultados de la regresión se guardan en una lista global regresiones con las siguientes propiedades: - x_vals y y_vals son los puntos calculados para la gráfica. - label etiqueta la línea de regresión con el tipo correspondiente. - color, line_width, marker_type, marker_color, y point_size definen la apariencia de la línea y los puntos.
La función no retorna ningún valor explícito.
Notas:#
La variable global data debe estar cargada antes de llamar a esta función.
La variable global regresiones es utilizada para almacenar múltiples regresiones.
Se espera que RegressionAnalysis sea una clase que implemente los métodos linear_regression, polynomial_regression e interpolation.
Excepciones:#
Muestra un mensaje de error si no hay datos cargados para las columnas x e y.
Ejemplo de uso:#
graficar_regresion(“lineal”) # Realiza y grafica una regresión lineal
def graficar_regresion(tipo): global regresiones x_col = columna_x.get() y_col = columna_y.get() if x_col is None or y_col is None: messagebox.showerror("Error", "No hay datos cargados para realizar la regresión.") return # Crear la instancia de RegressionAnalysis pasando el DataFrame directamente reg_analysis = RegressionAnalysis(data) if tipo == 'lineal': # Llamar a la función linear_regression con return_metrics=False x_vals, y_vals, ecuacion = reg_analysis.linear_regression(x_col, y_col, ax1=ax, return_metrics=False) elif tipo == 'polinomial': x_vals, y_vals, ecuacion = reg_analysis.polynomial_regression(x_col, y_col, ax1=ax, return_metrics=False) elif tipo == 'interpolacion': x_vals, y_vals, ecuacion = reg_analysis.interpolation(x_col, y_col, ax1=ax, return_metrics=False) # Guardar los datos de la regresión regresiones.append({ 'x_vals': x_vals, 'y_vals': y_vals, 'label': f"Regresión {tipo.capitalize()}", 'color': 'red', 'line_width': 1.0, 'marker_type': 'o', 'marker_color': 'red', 'point_size': 5 })
- src.graficador.update_regresion_property(regresion, property_type, new_value=None)#
Actualiza las propiedades visuales de una línea de regresión y actualiza la gráfica.
Parametros#
- regresiondict
Diccionario que contiene los datos y propiedades visuales de la regresión.
- property_typestr
Tipo de propiedad a modificar (“line_color”, “line_width”, “marker_type”, “marker_color”, “point_size”).
- new_valueany, opcional
Nuevo valor para la propiedad especificada. Si no se proporciona, se abre un cuadro de diálogo para seleccionar el color.
def update_regresion_property(regresion, property_type, new_value=None): if property_type == 'line_color': regresion['color'] = colorchooser.askcolor()[1] elif property_type == 'line_width': regresion['line_width'] = new_value elif property_type == 'marker_type': regresion['marker_type'] = new_value elif property_type == 'marker_color': regresion['marker_color'] = colorchooser.askcolor()[1] elif property_type == 'point_size': regresion['point_size'] = new_value # Redibujar la gráfica graficar_datos()
- src.graficador.grafica_ventana_regresion(master, tipo)#
Crea una ventana emergente para personalizar visualmente las líneas de regresión. Esta ventana permite cambiar propiedades como color, grosor de línea y tipo de marcador para la línea de regresión seleccionada.
Parametros#
- mastertkinter.Tk
Ventana principal de la aplicación.
- tipo_regresionstr
Tipo de regresión que se está personalizando (“lineal”, “polinomial”, “interpolacion”).
Variables globales#
- regresioneslist
Lista que contiene las regresiones realizadas, con sus datos y propiedades visuales.
def grafica_ventana_regresion(master, tipo): global personalizacion_ventana if personalizacion_ventana is not None and personalizacion_ventana.winfo_exists(): personalizacion_ventana.lift() return personalizacion_ventana = Toplevel(master) personalizacion_ventana.title(f"Personalización de Regresión {tipo.capitalize()}") personalizacion_ventana.geometry("400x400") regresion = next( (reg for reg in regresiones if tipo.strip().lower() in reg['label'].strip().lower()), None ) if regresion is None: messagebox.showerror("Error", f"No se encontró una regresión del tipo {tipo}.") personalizacion_ventana.destroy() return # Botón para cambiar el color de la línea Button(personalizacion_ventana, text="Color de Línea", command=lambda: update_regresion_property(regresion, 'line_color')).pack(pady=10) # Slider para cambiar el grosor de la línea Label(personalizacion_ventana, text="Grosor de Línea:").pack(pady=5) line_width_slider = Scale(personalizacion_ventana, from_=0.5, to=10, resolution=0.1, orient=HORIZONTAL, command=lambda value: update_regresion_property(regresion, 'line_width', float(value))) line_width_slider.set(regresion.get('line_width', 1.0)) line_width_slider.pack(pady=5) # Combobox para cambiar el tipo de marcador Label(personalizacion_ventana, text="Tipo de Marcador:").pack(pady=5) marker_options = ['o', 'x', '^', 's', '*'] marker_var = StringVar(value=regresion.get('marker_type', 'o')) marker_menu = ttk.Combobox(personalizacion_ventana, textvariable=marker_var, values=marker_options) marker_menu.pack(pady=5) marker_menu.bind("<<ComboboxSelected>>", lambda event: update_regresion_property(regresion, 'marker_type', marker_var.get())) # Botón para cambiar el color del marcador Button(personalizacion_ventana, text="Color del Marcador", command=lambda: update_regresion_property(regresion, 'marker_color')).pack(pady=10) # Slider para cambiar el tamaño del marcador Label(personalizacion_ventana, text="Tamaño del Marcador:").pack(pady=5) point_size_slider = Scale(personalizacion_ventana, from_=1, to=20, resolution=1, orient=HORIZONTAL, command=lambda value: update_regresion_property(regresion, 'point_size', float(value))) point_size_slider.set(regresion.get('point_size', 5)) point_size_slider.pack(pady=5) # Centrar la ventana personalizacion_ventana.update_idletasks() centrar_ventana(raiz, personalizacion_ventana) # Hacer que la ventana emergente sea modal personalizacion_ventana.transient(raiz) personalizacion_ventana.grab_release()
- src.graficador.apply_title_changes(title_size_var, title_fuente_var, titulo_grafica_entry)#
Aplica los cambios en el título de la gráfica, incluyendo el texto, tamaño de fuente y estilo de fuente, de acuerdo a los valores seleccionados por el usuario.
Parámetros#
- title_size_vartkinter.IntVar
Variable del tamaño de la fuente del título de la gráfica.
- title_fuente_vartkinter.StringVar
Variable del estilo de fuente del título de la gráfica.
- titulo_grafica_entrytkinter.Entry
Campo de entrada del nuevo texto para el título de la gráfica.
Variables globales#
- title_sizeint
Tamaño de la fuente del título de la gráfica.
- title_fuentestr
Estilo de la fuente utilizado para el título de la gráfica.
- titulo_graficatkinter.StringVar
Variable de texto para el título de la gráfica, que almacena el valor actual y el nuevo título.
def apply_title_changes(title_size_var, title_fuente_var, titulo_grafica_entry): global title_size, title_fuente, titulo_grafica titulo_grafica.set(titulo_grafica_entry.get()) # Obtener valores seleccionados title_size = int(title_size_var.get()) title_fuente = title_fuente_var.get() # Actualizar el título de la gráfica ax.set_title(titulo_grafica.get(), fontsize=title_size, fontname=title_fuente) canvas.draw()
- src.graficador.grafica_ventana_title(master)#
Abre una ventana emergente que permite al usuario personalizar el título de la gráfica, incluyendo el texto, tamaño de la fuente y el estilo de la fuente.
Parámetros#
- master :
Ventana principal de la aplicación.
Variables globales#
- personal_ventana_titletkinter.Toplevel
Ventana emergente de personalización del título de la gráfica.
- titulo_graficatkinter.StringVar
Variable del título actual de la gráfica.
def grafica_ventana_title(master): global personal_ventana_title, title_fuente # Verificar si la ventana ya está abierta if personal_ventana_title is not None and personal_ventana_title.winfo_exists(): personal_ventana_title.lift() # Lleva la ventana al frente return # No abrir otra ventana # Crear nueva ventana personal_ventana_title = Toplevel(master) personal_ventana_title.title("Personalización de Título") personal_ventana_title.geometry("300x250") # Nombre del Título Label(personal_ventana_title, text="Ingrese el Título:").pack(pady=10) titulo_grafica_entry = Entry(personal_ventana_title) titulo_grafica_entry.insert(0, titulo_grafica.get()) # Mostrar el título actual titulo_grafica_entry.pack(pady=5) # Selección del tamaño de letra (8,10,12,...) Label(personal_ventana_title, text="Tamaño de la letra:").pack() title_size_options = [8, 10, 12, 14, 16, 18, 20] # Tamaños de letra disponibles title_size_var = StringVar(value=str(title_size)) # Valor actual del tamaño # Crear un Combobox para seleccionar el tamaño de letra title_size_combobox = ttk.Combobox(personal_ventana_title, textvariable=title_size_var, values=title_size_options) title_size_combobox.pack(pady=5) # Selección de la fuente Label(personal_ventana_title, text="Fuente de la letra:").pack(pady=5) fuentes_disponibles = sorted(font.families()) if "title_fuente" not in globals() or not title_fuente: title_fuente = fuentes_disponibles[0] title_fuente_var = StringVar(value=title_fuente) # Usar Combobox para las fuentes fuente_combobox = ttk.Combobox(personal_ventana_title, textvariable=title_fuente_var, values=fuentes_disponibles, state="readonly") fuente_combobox.pack(pady=5) # Botón para aplicar los cambios Button(personal_ventana_title, text="Aplicar Cambios", command=lambda: apply_title_changes(title_size_var, title_fuente_var, titulo_grafica_entry)).pack(pady=10) # Actualizar para obtener las dimensiones de la ventana emergente personal_ventana_title.update_idletasks() centrar_ventana(raiz, personal_ventana_title) # Hacer que la ventana emergente sea modal personal_ventana_title.transient(raiz) personal_ventana_title.grab_set() raiz.wait_window(personal_ventana_title)
- src.graficador.apply_xaxis_changes(ejex_size_var, ejex_fuente_var, ejex_titulo_entry)#
Aplica los cambios en el título del eje X de la gráfica, incluyendo el texto, tamaño de fuente y estilo de fuente, de acuerdo a los valores seleccionados por el usuario.
Parámetros#
- ejex_size_vartkinter.IntVar
Variable vinculada al tamaño de la fuente del título del eje X.
- ejex_fuente_vartkinter.StringVar
Variable vinculada al estilo de fuente del título del eje X.
- ejex_titulo_entrytkinter.Entry
Campo de entrada que contiene el nuevo texto para el título del eje X.
Variables globales#
- ejex_sizeint
Tamaño de la fuente del título del eje X.
- ejex_shapestr
Estilo de la fuente utilizado para el título del eje X.
- ejex_titulotkinter.StringVar
Variable de texto para el título del eje X, que almacena el valor actual y el nuevo título.
def apply_xaxis_changes(ejex_size_var, ejex_fuente_var, ejex_titulo_entry): global ejex_size, ejex_shape, ejex_titulo ejex_titulo.set(ejex_titulo_entry.get()) # Obtener el nuevo título del eje X # Obtener valores seleccionados ejex_size = int(ejex_size_var.get()) ejex_shape = ejex_fuente_var.get() # Actualizar el título del eje X de la gráfica ax.set_xlabel(ejex_titulo.get(), fontsize=ejex_size, fontname=ejex_shape) # Redibujar la gráfica canvas.draw()
- src.graficador.grafica_ventana_ejex(master)#
Abre una ventana emergente que permite al usuario personalizar el título del eje X de la gráfica. El usuario puede modificar el texto, el tamaño de la fuente y el estilo de la fuente del eje X.
Parámetros#
- master :
La ventana principal desde la que se abrirá la ventana emergente de personalización.
Variables globales#
- ventana_ejextkinter.Toplevel
Ventana emergente de personalización del eje X.
- ejex_titulotkinter.StringVar
Variable de texto del título actual del eje X.
- ejex_sizeint
Tamaño de la fuente del título del eje X.
- ejex_shapestr
Estilo de la fuente utilizada para el título del eje X.
def grafica_ventana_ejex(master): global ventana_ejex, ejex_shape # Verificar si la ventana ya está abierta if ventana_ejex is not None and ventana_ejex.winfo_exists(): ventana_ejex.lift() # Lleva la ventana al frente return # No abrir otra ventana # Crear nueva ventana ventana_ejex = Toplevel(master) ventana_ejex.title("Personalización Eje x") ventana_ejex.geometry("300x250") # Nombre del Título Label(ventana_ejex, text="Ingrese Eje x:").pack(pady=10) titulo_ejex_var = Entry(ventana_ejex) titulo_ejex_var.insert(0, ejex_titulo.get()) # Mostrar el título actual titulo_ejex_var.pack(pady=5) # Selección del tamaño de letra (8,10,12,...) Label(ventana_ejex, text="Tamaño de la letra:").pack() ejex_size_options = [8, 10, 12, 14, 16, 18, 20] # Tamaños de letra disponibles ejex_size_var = StringVar(value=str(ejex_size)) # Valor actual del tamaño # Crear un Combobox para seleccionar el tamaño de letra ejex_size_combobox = ttk.Combobox(ventana_ejex, textvariable=ejex_size_var, values=ejex_size_options) ejex_size_combobox.pack(pady=5) # Selección de la fuente Label(ventana_ejex, text="Fuente de la letra:").pack(pady=5) fuentes_disponibles = sorted(font.families()) if "ejex_shape" not in globals() or not title_fuente: ejex_shape = fuentes_disponibles[0] ejex_fuente_var = StringVar(value=ejex_shape) # Valor actual de la fuente # Usar Combobox para las fuentes fuente_combobox = ttk.Combobox(ventana_ejex, textvariable=ejex_fuente_var, values=fuentes_disponibles, state="readonly") fuente_combobox.pack(pady=5) # Botón para aplicar los cambios Button(ventana_ejex, text="Aplicar Cambios", command=lambda: apply_xaxis_changes(ejex_size_var, ejex_fuente_var,titulo_ejex_var)).pack(pady=10) # Actualizar para obtener las dimensiones de la ventana emergente ventana_ejex.update_idletasks() centrar_ventana(raiz, ventana_ejex) # Hacer que la ventana emergente sea modal ventana_ejex.transient(raiz) ventana_ejex.grab_set() raiz.wait_window(ventana_ejex)
- src.graficador.apply_yaxis_changes(ejey_size_var, ejey_fuente_var, ejey_titulo_entry)#
Aplica los cambios de personalización al título del eje Y de la gráfica, como el tamaño y el tipo de fuente.
Parámetros#
- ejey_size_vartkinter.StringVar
Variable del tamaño de la fuente para el título del eje Y.
- ejey_fuente_vartkinter.StringVar
Variable de la fuente seleccionada para el título del eje Y.
- ejey_titulo_entrytkinter.Entry
Campo de texto donde se ingresa el nuevo título del eje Y.
Variables globales#
- ejey_sizeint
Tamaño de la fuente para el título del eje Y.
- ejey_shapestr
Tipo de fuente para el título del eje Y.
- ejey_titulotkinter.StringVar
Variable de texto que contiene el título del eje Y.
def apply_yaxis_changes(ejey_size_var, ejey_fuente_var, ejey_titulo_entry): global ejey_size, ejey_shape, ejey_titulo ejey_titulo.set(ejey_titulo_entry.get()) # Obtener el nuevo título del eje X # Obtener valores seleccionados ejey_size = int(ejey_size_var.get()) ejey_shape = ejey_fuente_var.get() # Actualizar el título del eje X de la gráfica ax.set_ylabel(ejey_titulo.get(), fontsize=ejey_size, fontname=ejey_shape) # Redibujar la gráfica canvas.draw()
- src.graficador.grafica_ventana_ejey(master)#
Abre una ventana emergente para personalizar el título del eje Y de la gráfica, permitiendo modificar el texto, el tamaño de la fuente y la fuente de la letra.
Parámetros#
- mastertkinter.Tk
Ventana principal de la aplicación.
Variables globales#
- ventana_ejeytkinter.Toplevel
La ventana emergente de personalización del eje Y.
- ejey_titulotkinter.StringVar
Variable del título del eje Y de la gráfica.
- ejey_sizeint
Tamaño de la fuente para el título del eje Y.
- ejey_shapestr
Tipo de fuente para el título del eje Y.
def grafica_ventana_ejey(master): global ventana_ejey, ejey_shape # Verificar si la ventana ya está abierta if ventana_ejey is not None and ventana_ejey.winfo_exists(): ventana_ejey.lift() # Lleva la ventana al frente return # No abrir otra ventana # Crear nueva ventana ventana_ejey = Toplevel(master) ventana_ejey.title("Personalización Eje y") ventana_ejey.geometry("300x250") # Nombre del Título Label(ventana_ejey, text="Ingrese Eje y:").pack(pady=10) titulo_ejey_var = Entry(ventana_ejey) titulo_ejey_var.insert(0, ejey_titulo.get()) # Mostrar el título actual titulo_ejey_var.pack(pady=5) # Selección del tamaño de letra (8,10,12,...) Label(ventana_ejey, text="Tamaño de la letra:").pack() ejey_size_options = [8, 10, 12, 14, 16, 18, 20] # Tamaños de letra disponibles ejey_size_var = StringVar(value=str(ejey_size)) # Valor actual del tamaño # Crear un Combobox para seleccionar el tamaño de letra ejey_size_combobox = ttk.Combobox(ventana_ejey, textvariable=ejey_size_var, values=ejey_size_options) ejey_size_combobox.pack(pady=5) # Selección de la fuente Label(ventana_ejey, text="Fuente de la letra:").pack(pady=5) fuentes_disponibles = sorted(font.families()) if "ejey_shape" not in globals() or not title_fuente: ejey_shape = fuentes_disponibles[0] ejey_fuente_var = StringVar(value=ejey_shape) # Valor actual de la fuente # Usar Combobox para las fuentes fuente_combobox = ttk.Combobox(ventana_ejey, textvariable=ejey_fuente_var, values=fuentes_disponibles, state="readonly") fuente_combobox.pack(pady=5) # Botón para aplicar los cambios Button(ventana_ejey, text="Aplicar Cambios", command=lambda: apply_yaxis_changes(ejey_size_var, ejey_fuente_var,titulo_ejey_var)).pack(pady=10) # Actualizar para obtener las dimensiones de la ventana emergente ventana_ejey.update_idletasks() centrar_ventana(raiz, ventana_ejey) # Hacer que la ventana emergente sea modal ventana_ejey.transient(raiz) ventana_ejey.grab_set() raiz.wait_window(ventana_ejey)
- src.graficador.on_double_click(event)#
Detecta un doble clic en los títulos de la gráfica (título principal, título del eje X o título del eje Y) y abre la ventana de edición correspondiente para personalizar el título del eje o gráfico.
Parámetros#
- eventmatplotlib.backend_bases.MouseEvent
El evento de clic que contiene la información sobre la posición del clic y si es un doble clic.
Variables globales#
- raiztkinter.Tk
La ventana principal de la aplicación.
def on_double_click(event): if event.dblclick: # Coordenadas del clic en la ventana gráfica x, y = event.x, event.y # Obtener la posición del título bbox_title = ax.title.get_window_extent(canvas.get_renderer()) bbox_xlabel = ax.xaxis.label.get_window_extent(canvas.get_renderer()) bbox_ylabel = ax.yaxis.label.get_window_extent(canvas.get_renderer()) # Comprobar si el clic fue en el título de la gráfica if bbox_title.contains(x, y): grafica_ventana_title(raiz) # Usar la ventana principal 'raiz' para abrir la personalización # Comprobar si el clic fue en el título de la gráfica elif bbox_xlabel.contains(x, y): grafica_ventana_ejex(raiz) # Comprobar si el clic fue hecho en Eje y elif bbox_ylabel.contains(x,y): grafica_ventana_ejey(raiz)
- src.graficador.update_x_limits(master)#
Muestra una ventana emergente para actualizar los límites del eje X de la gráfica.
Parámetros#
- mastertkinter.Tk
La ventana principal de la aplicación.
Variables globales#
- ventana_lim_xtkinter.Toplevel
La ventana emergente creada para la actualización de los límites del eje X.
def update_x_limits(master): global ventana_lim_x # Obtener las columnas seleccionadas columna_x_seleccionada = columna_x.get() # Obtener los datos de la columna seleccionada datos_x = data[columna_x_seleccionada] # Valores predeterminados x_min_datos = datos_x.min() x_max_datos = datos_x.max() # Crear nueva ventana ventana_lim_x = Toplevel(master) ventana_lim_x.title("Límites Eje X") ventana_lim_x.geometry("300x250") # Etiquetas y campos de entrada para x_min y x_max Label(ventana_lim_x, text="Ingrese x_min:").pack(pady=5) x_min_entry = Entry(ventana_lim_x) x_min_entry.insert(0, str(x_min_datos)) # Valor de x_min x_min_entry.pack() Label(ventana_lim_x, text="Ingrese x_max:").pack(pady=5) x_max_entry = Entry(ventana_lim_x) x_max_entry.insert(0, str(x_max_datos)) # Valor de x_max x_max_entry.pack() # Botón para actualizar los límites de X Button(ventana_lim_x, text="Actualizar Límites", command=lambda: set_x_limits(x_min_entry, x_max_entry)).pack(pady=10) # Actualizar para obtener las dimensiones de la ventana emergente ventana_lim_x.update_idletasks() centrar_ventana(raiz, ventana_lim_x) # Hacer que la ventana emergente sea modal ventana_lim_x.transient(raiz) ventana_lim_x.grab_set() raiz.wait_window(ventana_lim_x)
- src.graficador.set_x_limits(x_min_entry, x_max_entry)#
Actualiza los límites del eje X según los valores ingresados por el usuario en la ventana emergente.
Parámetros#
- x_min_entrytkinter.Entry
Campo de entrada dl valor para el límite inferior del eje X (x_min).
- x_max_entrytkinter.Entry
Campo de entrada del valor para el límite superior del eje X (x_max).
Variables globales#
- x_limitslist
Lista que almacena los límites actuales del eje X [x_min, x_max].
- origx_limlist
Copia de los límites originales del eje X, utilizada para restaurar los valores iniciales si es necesario.
def set_x_limits(x_min_entry, x_max_entry): global x_limits, origx_lim try: # Obtener las columnas seleccionadas columna_x_seleccionada = columna_x.get() # Obtener los datos de la columna seleccionada datos_x = data[columna_x_seleccionada] # Valores predeterminados x_min_datos = datos_x.min() x_max_datos = datos_x.max() # Validar y asignar los límites ingresados por el usuario x_min = float(x_min_entry.get()) if x_min_entry.get() else x_min_datos x_max = float(x_max_entry.get()) if x_max_entry.get() else x_max_datos if x_min < x_max: x_limits = [x_min, x_max] # Límite actual se actualiza if origx_lim is None: # Solo actualiza los límites originales si no se han definido origx_lim = [x_min_datos, x_max_datos] else: origx_lim = [x_min, x_max] print(f"Límites del eje X actualizados: {origy_lim}") graficar_datos() # Redibuja la gráfica con los nuevos límites ventana_lim_x.destroy() # Cerrar la ventana emergente else: messagebox.showerror("Error","El valor de x_min debe ser menor que x_max.") except ValueError: messagebox.showerror("Error","Por favor, ingrese valores numéricos válidos.")
- src.graficador.update_y_limits(master)#
Muestra una ventana emergente para actualizar los límites del eje Y.
Parámetros#
- mastertkinter.Tk
La ventana principal de la aplicación. Es el contenedor sobre el que se crea la ventana emergente.
Variables globales#
- ventana_lim_ytkinter.Toplevel
Ventana emergente que permite al usuario ingresar los límites del eje Y.
def update_y_limits(master): global ventana_lim_y # Obtener las columnas seleccionadas columna_y_seleccionada = columna_y.get() # Obtener los datos de la columna seleccionada datos_y = data[columna_y_seleccionada] # Valores predeterminados y_min_datos = datos_y.min() y_max_datos = datos_y.max() # Crear nueva ventana ventana_lim_y = Toplevel(master) ventana_lim_y.title("Límites Eje Y") ventana_lim_y.geometry("300x250") # Etiquetas y campos de entrada para x_min y x_max Label(ventana_lim_y, text="Ingrese y_min:").pack(pady=5) y_min_entry = Entry(ventana_lim_y) y_min_entry.insert(0, str(y_min_datos)) # Valor de y_min y_min_entry.pack() Label(ventana_lim_y, text="Ingrese y_max:").pack(pady=5) y_max_entry = Entry(ventana_lim_y) y_max_entry.insert(0, str(y_max_datos)) # Valor de y_max y_max_entry.pack() # Botón para actualizar los límites de X Button(ventana_lim_y, text="Actualizar Límites", command=lambda: set_y_limits(y_min_entry, y_max_entry)).pack(pady=10) # Actualizar para obtener las dimensiones de la ventana emergente ventana_lim_y.update_idletasks() centrar_ventana(raiz, ventana_lim_y) # Hacer que la ventana emergente sea modal ventana_lim_y.transient(raiz) ventana_lim_y.grab_set() raiz.wait_window(ventana_lim_y)
- src.graficador.set_y_limits(y_min_entry, y_max_entry)#
Actualiza los límites del eje Y según los valores ingresados por el usuario en la ventana emergente.
Parámetros#
- y_min_entrytkinter.Entry
Campo de entrada del valor mínimo para el eje Y.
- y_max_entrytkinter.Entry
Campo de entrada del valor máximo para el eje Y.
Variables globales#
- y_limitslist
Lista que almacena los valores actuales de los límites del eje Y [y_min, y_max].
- origy_limlist
Copia de los límites originales del eje Y, utilizada para restaurar los valores si es necesario.
def set_y_limits(y_min_entry, y_max_entry): global y_limits, origy_lim try: # Obtener las columnas seleccionadas columna_y_seleccionada = columna_y.get() # Obtener los datos de la columna seleccionada datos_y = data[columna_y_seleccionada] # Valores predeterminados y_min_datos = datos_y.min() y_max_datos = datos_y.max() # Validar y asignar los límites ingresados por el usuario y_min = float(y_min_entry.get()) if y_min_entry.get() else y_min_datos y_max = float(y_max_entry.get()) if y_max_entry.get() else y_max_datos if y_min < y_max: y_limits = [y_min, y_max] # Límite actual se actualiza if origy_lim is None: # Solo actualiza los límites originales si no se han definido origy_lim = [y_min_datos, y_max_datos] else: origy_lim = [y_min, y_max] print(f"Límites del eje Y actualizados: {origy_lim}") graficar_datos() # Redibuja la gráfica con los nuevos límites ventana_lim_y.destroy() # Cerrar la ventana emergente else: messagebox.showerror("Error","El valor de y_min debe ser menor que y_max.") except ValueError: messagebox.showerror("Error","Por favor, ingrese valores numéricos válidos.")
- src.graficador.zoom(event=None, reset=False)#
Ajuste del nivel de zoom en la gráfica redibujando los ejes a partir de nuevos límites que se actualizarán dependiendo de la amplificación que de el usuario. El nivel de zoom es controlado por el valor de una barra deslizante [scale] y la gráfica es redibujada en función de los límites ajustados. También se actualiza el porcentaje de zoom mostrado en pantalla [zoom_label]. Si se desea volver al tamaño original de la gráfica este se reestablecera cuando [reset] sea True.
Parámetros#
- eventtkinter.Event, optional
Evento que dispara la acción de zoom.
- resetbool, optional
Si True, restablece los límites originales de la gráfica.
Variables globales#
- x_limitslist
Lista que contiene los límites actuales del eje “x” en la forma [xmin, xmax].
- y_limitslist
Lista que contiene los límites actuales del eje “y” en la forma [ymin, ymax].
- returns:
La función no retorna ningún valor, simplemente actualiza la gráfica y la interfaz de usuario.
- rtype:
None
def zoom(event=None,reset=False): global x_limits, y_limits, origx_lim, origy_lim # Variables globales, límites de 'x' y 'y' if reset: # Restablecer límites originales x_limits = origx_lim.copy() y_limits = origy_lim.copy() zoom_label.config(text="Zoom: 100%") # Restablecer la etiqueta de zoom x_scale.set(0) # Resetear la barra de zoom de X y_scale.set(0) # Resetear la barra de zoom de Y else: # Obtener los valores de las barras deslizantes para cada eje x_zoom_level = x_scale.get() y_zoom_level = y_scale.get() x_mid = (origx_lim[1] + origx_lim[0]) / 2 # Punto medio 'x' x_zoom_factor = 1 + x_zoom_level x_range = (origx_lim[1] - origx_lim[0]) / x_zoom_factor x_limits = [x_mid - x_range / 2, x_mid + x_range / 2] y_mid = (origy_lim[1] + origy_lim[0]) / 2 # Punto medio 'y' y_zoom_factor = 1 + y_zoom_level y_range = (origy_lim[1] - origy_lim[0]) / y_zoom_factor y_limits = [y_mid - y_range / 2, y_mid + y_range / 2] # Actualizar la etiqueta de porcentaje de zoom para cada eje x_zoom_percentage = int((x_zoom_level / 10) * 100) y_zoom_percentage = int((y_zoom_level / 10) * 100) zoom_label.config(text=f"Zoom X: {x_zoom_percentage}% | Zoom Y: {y_zoom_percentage}%") # Actualizar los límites de la gráfica ax.set_xlim(x_limits) ax.set_ylim(y_limits) canvas.draw()
- src.graficador.on_press(event)#
Evento que permite inicializar un evento con un clic siempre y cuando este se haya realizado dentro de la gráfica, es decir, definido dentro de los límites de la definición para matplotlib.
Parámetros#
- eventmatplotlib.backend_bases.MouseEvent
Evento que contiene la información del clic del mouse dentro de los límites de la gráfica y almacenando las coordenadas [x,y] del clic realizado.
Variables globales#
- is_draggingbool
Indicador que se establece en True cuando el usuario está arrastrando el mouse.
- start_xfloat
Coordenada “x” donde se inició el clic en la gráfica.
- start_yfloat
Coordenada “y” donde se inició el clic en la gráfica.
- returns:
La función no retorna ningún valor, simplemente actualiza datos.
- rtype:
None
def on_press(event): global is_dragging, start_x, start_y if event.inaxes: is_dragging = True # Interacción con la gráfica start_x, start_y = event.xdata, event.ydata # Almacenamiento de datos iniciales de clic
- src.graficador.on_release(event)#
Evento que permite finalizar la función anterior de interacción del usuario y la gráfica a través del mouse. A demás, permite que la acción solo se realice siempre y cuando el usuario deslice mientras hace el clic, al soltar el clic se finaliza la acción.
Parámetros#
- eventmatplotlib.backend_bases.MouseEvent
Evento que contiene la información del clic del mouse dentro de los límites de la gráfica y almacenando las coordenadas [x,y] del clic realizado.
Variables globales#
- is_draggingbool
Indicador que se establece en False cuando el usuario suelta el botón del mouse, lo que indica que la interacción/arrastre ha finalizado.
- returns:
La función no retorna ningún valor, simplemente actualiza datos.
- rtype:
None
def on_release(event): global is_dragging is_dragging = False # Finalizar el evento de interacción al soltar el clic.
- src.graficador.on_motion(event)#
Evento que permite desplazar la gráfica mientras el usuario interactúa/arrastra el mouse, ajustando los límites de los ejes de acuerdo al desplazamiento del cursor.
Parámetros#
- eventmatplotlib.backend_bases.MouseEvent
Evento que contiene la información del clic del mouse dentro de los límites de la gráfica y almacenando las coordenadas [x,y] del clic realizado.
Variables globales#
- x_limitslist
Lista que contiene los límites actuales del eje “x” en la forma [xmin, xmax].
- y_limitslist
Lista que contiene los límites actuales del eje “y” en la forma [ymin, ymax].
- start_xfloat
Coordenada “x” donde se inició el clic en la gráfica.
- start_yfloat
Coordenada “y” donde se inició el clic en la gráfica.
Nota:#
Este evento solo se activa si la variable global is_dragging es True, lo que indica que el usuario ya ha iniciado el proceso de arrastre al presionar el botón del ratón en la gráfica (evento gestionado por la función on_press).
Nota:#
Este evento solo se activa si la variable global is_dragging es True, lo que indica que el usuario ya ha iniciado el proceso de arrastre al presionar el botón del ratón en la gráfica (evento gestionado por la función on_press).
def on_motion(event): global x_limits, y_limits, start_x, start_y, origx_lim, origy_lim if is_dragging and event.inaxes: # Verificación de interacción True and True # Calculo de diferencia entre el clic inicial y la posición actual del cursor dx = start_x - event.xdata dy = start_y - event.ydata # Redefinir los límites de acuerdo al desplazamiento x_limits = [x + dx for x in x_limits] y_limits = [y + dy for y in y_limits] # Sincronizar con los límites originales origx_lim = x_limits.copy() origy_lim = y_limits.copy() # Actualizar la gráfica dinámicamente ax.set_xlim(x_limits) ax.set_ylim(y_limits) canvas.draw()
- src.graficador.cerrar_ventana()#
Función que se llama al cerrar la ventana para borrar el archivo tmp_graph.pkl
def cerrar_ventana(): respuesta = messagebox.askyesno( "Confirmación de cierre", "¿Estás seguro de que quieres cerrar la aplicación?\nSe eliminarán los cambios realizados." ) if respuesta: # Si el usuario confirma archivo_tmp = "tmp_graph.pkl" if os.path.exists(archivo_tmp): os.remove(archivo_tmp) raiz.quit() # Esto cierra el mainloop de Tkinter