无法在同一图 MATPLOTLIB 上重新绘制图形 [英] Can't replot a graph on the same figure MATPLOTLIB

查看:105
本文介绍了无法在同一图 MATPLOTLIB 上重新绘制图形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先我要感谢一个用户@j_4321,他在这个问题上帮了我很多如何在不单击 MATPLOTLIB 的情况下使用鼠标绘制自动图形.

First I want to thank a user @j_4321 that helps me a lot in this problem How to plot an automatic graph using mouse without clicking MATPLOTLIB.

我很理解你的方法,但是我想用函数来做这个方法只是为了熟悉python.

I really understand your method, but I want to do this method using functions only in order to familiarize with python.

但是每次移动鼠标时使用这种方法,都会弹出一个新图形,我想要做的是在同一个图形上重新绘制.

but with this method every time when I move my mouse, a new figure pops up and what I want to do is to replot on the same figure.

这是我的代码:

import tkinter as tk
from tkinter import messagebox, filedialog
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
from matplotlib.figure import Figure
import numpy as np
import os
from readgssi import readgssi

# data
Data = []
xData = []
xAxes = []


def readDZT():
    global xAxes, Data
    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))
        xAxes = X_Axes[2::1]
        df = pd.DataFrame(arrs[0])
        Data = df.iloc[2::1, 0::1]
        fig1 = plt.figure()
        # clear plots
        plt.clf()
        # plot 2D map
        plt.imshow(Data, aspect='auto', cmap='bone')
        plt.connect('motion_notify_event', mouse_move)
        fig1.canvas.draw_idle()
        plt.show()

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


def mouse_move(event):
    x = event.xdata
    print(x)
    if len(Data) and x is not None:  # there is something to plot
        fig2 = plt.figure()
        plt.clf()
        x = int(x)
        plt.plot(xAxes, Data[x])
        fig2.canvas.draw_idle()
        plt.show()


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)

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

root.mainloop()

你有什么建议吗?

推荐答案

之所以每次移动鼠标都会弹出一个新图形,是因为移动鼠标触发了mouse_move() 并且在这个里面函数,您使用 fig2 = plt.figure() 创建一个新图形.

The reason why a new figure pops up every time you move the mouse is because moving the mouse triggers mouse_move() and inside this function, you create a new figure with fig2 = plt.figure().

为避免这种情况,您可以在函数之外创建两个图形.但是,当您绘制图形时,您必须将 plt.imshow 替换为 ax1.imshow 并将 plt.plot 替换为 ax2.plot 得到右图的图形.而且 plt.clf() 必须替换为 ax1.clear()/ax2.clear().

To avoid that, you can create both figures outside the functions. But then, when you plot the graphs, you have to replace plt.imshow by ax1.imshow and plt.plot by ax2.plot to get the graphs on the right figure. And also plt.clf() has to be replaced by ax1.clear()/ax2.clear().

最后,您可以从 mouse_move() 中删除 plt.show(),因为 matplotlib 事件循环已经在运行(在 readDZT() 中调用)代码>).只要显示绘图,对 plt.show() 的调用就会冻结 tkinter GUI,因此我还在 readDZT()<中添加了 root.update_idletasks()/code> 使消息框在启动 matplotlib 的事件循环之前消失.

Finally, you can remove the plt.show() from mouse_move() since matplotlib event loop is already running (called in readDZT()). The call to plt.show() freezes the tkinter GUI as long as the plots are displayed so I also added root.update_idletasks() in readDZT() to make the messagebox disappear before launching matplotlib's event loop.

完整代码如下:

import tkinter as tk
from tkinter import messagebox, filedialog
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
from matplotlib.figure import Figure
import numpy as np
import os
from readgssi import readgssi

# data
Data = []
xData = []
xAxes = []

# create plots
fig1 = plt.figure()
ax1 = fig1.add_subplot(111)
fig2 = plt.figure()
ax2 = fig2.add_subplot(111)

def readDZT():
    global xAxes, Data
    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))
        xAxes = X_Axes[2::1]
        df = pd.DataFrame(arrs[0])
        Data = df.iloc[2::1, 0::1]
        # clear plots
        ax1.clear()
        ax2.clear()
        # plot 2D map in ax1
        ax1.imshow(Data, aspect='auto', cmap='bone')
        fig1.canvas.mpl_connect('motion_notify_event', mouse_move)
        fig1.canvas.draw_idle()
        fig2.canvas.draw_idle()
        # force update of tkinter GUI before launching matplotlib's event loop
        root.update_idletasks()
        plt.show()
    else:
        messagebox.showwarning("WARNING", "You Have Been Selected a Different Format")


def mouse_move(event):
    x = event.xdata
    print(x)
    if len(Data) and x is not None:  # there is something to plot
        ax2.clear()  # clear second plot
        x = int(x)
        ax2.plot(xAxes, Data[x])  # plot slice in ax2
        fig2.canvas.draw_idle()

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)

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

root.mainloop()    

这篇关于无法在同一图 MATPLOTLIB 上重新绘制图形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆