Joseph Dougmi
Joseph Dougmi

Reputation: 27

How to plot an automatic graph using mouse without clicking MATPLOTLIB

I'm looking to plot Data automatically using mouse without clicking From a DZT file. i Created a program in order to plot data as you can see in this graph:enter image description here

As you can see in this picture, x axes going from 0 to 3525 ans every x is a signal so i have more than 3500 signals making this graph.

for exemple if i want to see the signal of x=999, it looks like this.enter image description here

what i want really to do is every time when i pass my mouse without clicking on the graph it should plot it's signal automatically .

i try to use a lot of methods but rally i dont know how to do it.

i'll be grateful for your help

this is my file: https://www.grosfichiers.com/mvabGETFfna

This is my program:

from tkinter import *
from tkinter import messagebox, filedialog
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import os
from readgssi import readgssi

root = Tk()
root.title("IHM")
root.geometry("1000x800")

Resources_frame = LabelFrame(root, bd=2, relief=GROOVE, text="Conversion Area")
Resources_frame.place(x=5, y=5, width=250, height=80)

lbl_ra = Label(Resources_frame, text="Select your File ")
lbl_ra.grid(row=0, column=0, sticky=W)
lbl_ra = Label(Resources_frame, text="Convert Selected file ")
lbl_ra.grid(row=1, column=0, sticky=W)
NumberOfSimples = ''
DataAScan = ''
Data = ''
xData = ''
xAxes = ''


def ReadDZT():
    file_path = filedialog.askopenfilename()
    file_name, file_extension = os.path.splitext(file_path)

    print(file_extension)
    if file_extension == '.DZT':
        messagebox.showinfo("INFO", "Your DZT File Has Been Selected Successfully")
        hdr, arrs, gps = readgssi.readgssi(infile=file_path, verbose=True)

        TimeRange = hdr['rhf_range']
        Samples = hdr['rh_nsamp']

        X_Axes = np.array(range(0, Samples))
        xAxes = X_Axes[2::1]

        df = pd.DataFrame(arrs[0])
        Data = df.iloc[2::1, 0::1]
        fig2 = plt.figure()
        plt.plot(xAxes, Data[999])
        plt.show()

        fig = plt.figure()
        plt.imshow(Data, aspect='auto', cmap='bone')
        plt.show()

    elif file_extension == '.csv':
        messagebox.showinfo("INFO", "Your CSV File Has Been Selected Successfully")
        df = pd.read_csv(file_path)
        NumberOfSimples = df.iloc[2::1, 0]
        Data = df.iloc[::1, ::1]
        DataAScan = df.iloc[2::1, 999]
        fig1 = plt.figure()
        plt.plot(NumberOfSimples, DataAScan)
        plt.show()
        fig2 = plt.figure()
        plt.imshow(Data, aspect='auto', cmap='bone')
        plt.show()
    else:
        messagebox.showwarning("WARNING", "You Have Been Selected a Different Format")


# =============Resources Buttons================#
btn_rs = Button(Resources_frame, relief=GROOVE, padx=8, pady=1, text="Browse", command=ReadDZT).grid(row=0,
                                                                                                     column=1)

root.mainloop()

Upvotes: 0

Views: 409

Answers (1)

j_4321
j_4321

Reputation: 16169

As indicated in the previous question Ploting a graph automatically using mouse coordinate (and I think this question should have been an edit of it), the mouse motion can be monitored with plt.connect('motion_notify_event', mouse_move). The slice of Data to be plotted in fig2 simply corresponds to the x-coordinate of the mouse, that is Data[int(event.xdata)] in mouse_move(event).

Therefore, in mouse_move(event), you:

  1. Clear the axis: ax2.clear() (where ax2 is the AxesSubplot object of fig2)
  2. Plot the slice ax2.plot(self.xAxes, self.Data[int(event.xdata)])
  3. Update the figure fig2.canvas.draw_idle()

However, I had issues with using simultaneously the matplotlib figures and the tkinter GUI because of the separate event loops. Therefore I embedded the figures in the tkinter GUI directly (see e.g. https://matplotlib.org/3.4.0/gallery/user_interfaces/embedding_in_tk_sgskip.html).

I also put the graph related code in a class to keep the loaded data in attributes to avoid using global variables.

import tkinter as tk
from tkinter import messagebox, filedialog
import pandas as pd
import matplotlib
matplotlib.use("TkAgg")
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
from matplotlib.figure import Figure
import numpy as np
import os
from readgssi import readgssi


class Graphs(tk.Toplevel):
    def __init__(self, master=None, **kw):
        tk.Toplevel.__init__(self, master, **kw)
        self.rowconfigure(0, weight=1)
        self.rowconfigure(2, weight=1)
        # data
        self.Data = []
        self.xData = []
        self.xAxes = []
        self.line = None

        # figure1 : 2D data map
        self.fig1 = Figure()
        self.ax1 = self.fig1.add_subplot(111)
        self.canvas1 = FigureCanvasTkAgg(self.fig1, self)
        self.canvas1.draw()
        self.canvas1.get_tk_widget().grid(sticky='ewsn')
        self.toolbar1 = NavigationToolbar2Tk(self.canvas1, self, pack_toolbar=False)
        self.toolbar1.grid(sticky="ew")

        # figure 2: slice plot
        self.fig2 = Figure()
        self.ax2 = self.fig2.add_subplot(111)
        self.canvas2 = FigureCanvasTkAgg(self.fig2, self)
        self.canvas2.draw()
        self.canvas2.get_tk_widget().grid(sticky='ewsn')
        self.toolbar2 = NavigationToolbar2Tk(self.canvas2, self, pack_toolbar=False)
        self.toolbar2.grid(sticky="ew")

        # bind plotting to mouse motion
        self.canvas1.mpl_connect('motion_notify_event', self.mouse_move)

    def mouse_move(self, event):
        x = event.xdata
        if len(self.Data) and x is not None:  # there is something to plot
            self.ax2.clear()
            x = int(x)
            self.ax2.plot(self.xAxes, self.Data[x])
            self.line.set_data([x, x], [len(self.Data), 0])
            self.canvas1.draw_idle()
            self.canvas2.draw_idle()

    def readDZT(self):
        file_path = filedialog.askopenfilename()
        file_name, file_extension = os.path.splitext(file_path)

        if file_extension == '.DZT':
            messagebox.showinfo("INFO", "Your DZT File Has Been Selected Successfully")
            hdr, arrs, gps = readgssi.readgssi(infile=file_path, verbose=True)

            Samples = hdr['rh_nsamp']

            X_Axes = np.array(range(0, Samples))
            self.xAxes = X_Axes[2::1]
            df = pd.DataFrame(arrs[0])
            self.Data = df.iloc[2::1, 0::1]

            # clear plots
            self.ax1.clear()
            self.ax2.clear()
            # plot slice
            self.ax2.plot(self.xAxes, self.Data[999])
            self.canvas2.draw_idle()
            # plot 2D map
            self.ax1.imshow(self.Data, aspect='auto', cmap='bone')
            self.line = self.ax1.plot([999, 999], [len(self.Data), 0], 'r')[0]
            self.ax1.set_ylim(len(self.Data), 0)
            self.canvas1.draw_idle()

        else:
            messagebox.showwarning("WARNING", "You Have Been Selected a Different Format")



root = tk.Tk()
root.title("IHM")
root.geometry("1000x800")

Resources_frame = tk.LabelFrame(root, bd=2, relief=tk.GROOVE, text="Conversion Area")
Resources_frame.place(x=5, y=5, width=250, height=80)

tk.Label(Resources_frame, text="Select your File ").grid(row=0, column=0, sticky=tk.W)
tk.Label(Resources_frame, text="Convert Selected file ").grid(row=1, column=0, sticky=tk.W)

graphs = Graphs(root)


btn_rs = tk.Button(Resources_frame, relief=tk.GROOVE, padx=8, pady=1, text="Browse",
                   command=graphs.readDZT).grid(row=0, column=1)

root.mainloop()

screenshot

Upvotes: 1

Related Questions