【问题标题】:How to plot an automatic graph using mouse without clicking MATPLOTLIB如何在不单击 MATPLOTLIB 的情况下使用鼠标绘制自动图形
【发布时间】:2021-07-21 17:47:50
【问题描述】:

我希望使用鼠标自动绘制数据,而无需单击从 DZT 文件。 我创建了一个程序来绘制数据,如下图所示:

正如您在这张图片中看到的,x axes 从 0 到 3525 以及每个 x 是一个信号,所以我有超过 3500 个信号来制作这个图表。

例如,如果我想查看x=999 的信号,它看起来像这样。

我真正想做的是每次当我通过鼠标而不点击图表时,它应该自动绘制它的信号。

我尝试了很多方法,但我不知道该怎么做。

感谢您的帮助

这是我的文件: https://www.grosfichiers.com/mvabGETFfna

这是我的程序:

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()

【问题讨论】:

  • 你想用鼠标调用函数吗?

标签: python matplotlib tkinter mouseevent


【解决方案1】:

如上一个问题Ploting a graph automatically using mouse coordinate(我认为这个问题应该是对它的编辑)所指出的,鼠标运动可以用plt.connect('motion_notify_event', mouse_move)监控。要在fig2 中绘制的Data 切片简单地对应于鼠标的x 坐标,即Data[int(event.xdata)] 中的mouse_move(event)

因此,在mouse_move(event),你:

  1. 清除轴:ax2.clear()(其中ax2AxesSubplotfig2 对象)
  2. 绘制切片ax2.plot(self.xAxes, self.Data[int(event.xdata)])
  3. 更新图fig2.canvas.draw_idle()

但是,由于单独的事件循环,我在同时使用 matplotlib 图形和 tkinter GUI 时遇到了问题。因此,我直接将图形嵌入到 tkinter GUI 中(参见例如https://matplotlib.org/3.4.0/gallery/user_interfaces/embedding_in_tk_sgskip.html)。

我还把图相关的代码放在一个类中,将加载的数据保存在属性中,避免使用全局变量。

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()

【讨论】:

  • 感谢您的反馈,我尝试执行该程序,但它给了我一个错误。 ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
  • 是的,对不起,我忘了在Data 周围加上len() 以检查它是否为空
  • 非常感谢,这真的很有帮助 :) 谢谢你,终于成功了
  • 我刚刚意识到雷达图在 y axes 中是倒数的,它应该从 250 开始到 0 而不是倒数
  • @JosephDougmi 之前没有注意 y 轴,现在已经修复了(我只是在 self.ax1.set_ylim(len(self.Data), 0) 中切换了限制)
猜你喜欢
  • 1970-01-01
  • 2020-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-15
相关资源
最近更新 更多