将绘图重新分级到偏移量

Moving the plot regrading to the offset

亲爱的,

我写这段代码是为了计算在绘图上两次鼠标点击之间的距离。现在,我试图根据计算出的偏移量将图向左或向右移动,以便两个图完全匹配。知道如何实现吗?我试过正常加减,但是没用。

import matplotlib.pyplot as plt
from matplotlib.widgets import Cursor
import mplcursors
from math import sqrt
import numpy as np 
import tkinter as tk
from tkinter import simpledialog

class DistancePlot:
    def __init__(self):
        
        ROOT = tk.Tk()
        ROOT.withdraw()
        ROOT.geometry("500x200")
        #my_frame = Frame(ROOT)
        #my_frame.pack(fill="both", expand=True)

        USER_INP = (simpledialog.askinteger(title="Plot dialig", 
                                  prompt="Enter the number of the plots "))
        
        if USER_INP is not None: 
            def f(x):
                return np.sin(x) + np.random.normal(scale=0.1, size=len(x))
            self.x = np.linspace(1, 10)
            self.fig, self.ax= plt.subplots()
            for i in range(USER_INP):
                plt.plot(self.x, f(self.x))

       
            self.ax.set_xlabel('X-axis')
            self.ax.set_ylabel('Y-axis')

            self.d1 = (0.0, 0.0)
            self.d2 = (0.0, 0.0)

            self.first_click = True

            self.cursor=Cursor(self.ax, horizOn=True, vertOn=True, color='black', linewidth=1.0)

            self.fig.canvas.mpl_connect('button_press_event', self.onclick)

            mplcursors.cursor(hover=True)
            plt.show()
            
        else: 
            def quit(self):
                self.ROOT.destroy()
        
    def onclick(self, event):
        z1, r1 = event.xdata, event.ydata
        print(z1, r1)

        if self.first_click:
            self.first_click = False
            self.d1 = (z1, r1)
        else:
            self.first_click = True
            self.d2 = (z1, r1)
            distance = sqrt((((self.d1[0]) - (self.d2[0])) ** 2) + (((self.d1[1]) - (self.d2[1])) ** 2))
            print("The shift between ", self.d1, "and", self.d2, "is", distance)
    
            
dp = DistancePlot()

评论中的答案很有帮助,但这不是我想要的,我尝试使用相同的逻辑来找到我的解决方案,但没有成功,我会与您分享。

import matplotlib.pyplot as plt
from matplotlib.widgets import Cursor
import mplcursors
import numpy as np
import tkinter as tk
#from tkinter import simpledialog

class DistancePlot:
    def __init__(self):
        ROOT = tk.Tk()
        ROOT.withdraw()
        ROOT.geometry("500x200")
#        USER_INP = 1
        
        #random sine wave
        x = np.linspace(1, 10)
        def f(x):
            return np.sin(x) + np.random.normal(scale=0.1, size=len(x)) 
        #fixed sine wave 
        time= np.arange(0, 10, 0.1)
        amplitude   = np.sin(time)
        
        self.fig, self.ax = plt.subplots()
        self.ax.plot(x, f(x))
        self.ax.plot(time, amplitude)
        self.ax.set_xlabel('X-axis')
        self.ax.set_ylabel('Y-axis')
        self.d1 = np.zeros(2)
        self.d2 = np.zeros(2)

        self.first_click = True
        self.cursor = Cursor(self.ax, horizOn=True, vertOn=True, color='black', linewidth=1)
        self.fig.canvas.mpl_connect('button_press_event', self.onclick)
        mplcursors.cursor(hover=True)
        plt.show()
            

    def onclick(self, event):
        z1, r1 = event.xdata, event.ydata
        print(z1, r1)
        if self.first_click:
            self.first_click = False
            self.d1 = np.array((z1, r1))
        else:
            self.first_click = True
            self.d2 = np.array((z1, r1))
            #distance = sqrt((((self.d1[0]) - (self.d2[0])) ** 2) + (((self.d1[1]) - (self.d2[1])) ** 2))
            #print("The distance between ", self.d1, "and", self.d2, "is", distance)
            delta = self.d2 - self.d1
            print("The delta between ", self.d1, "and", self.d2, "is", delta)
            if (abs(self.d2[0]) > abs(self.d1[0])).all():
                self.ax.lines[0].set_data(self.ax.lines[0].get_data() - delta.reshape(2,1))
                self.ax.relim()
                self.ax.autoscale_view()
                plt.draw()
                
            else: 
                self.ax.lines[0].set_data(self.ax.lines[0].get_data() + delta.reshape(2,1))
                self.ax.relim()
                self.ax.autoscale_view()
                plt.draw()

dp = DistancePlot()

我想要的是使用参考图并将其与另一个图匹配,如果我添加的图领先我希望它被减去,如果它滞后我希望它向前移动所以将它添加到增量.

这是一种方法,将第一条曲线移动给定距离。 Numpy 数组用于简化循环。 relim()autoscale_view() 重新计算 x 和 y 限制以再次将所有内容放入边距内(如果预期位移较小,可以跳过此步骤)。

import matplotlib.pyplot as plt
from matplotlib.widgets import Cursor
import mplcursors
from math import sqrt
import numpy as np
import tkinter as tk
from tkinter import simpledialog

class DistancePlot:
    def __init__(self):
        ROOT = tk.Tk()
        ROOT.withdraw()
        ROOT.geometry("500x200")
        USER_INP = 2
        # USER_INP = (simpledialog.askinteger(title="Plot dialig", prompt="Enter the number of the plots "))
        if USER_INP is not None:
            def f(x):
                return np.sin(x) + np.random.normal(scale=0.1, size=len(x))

            self.x = np.linspace(1, 10)
            self.fig, self.ax = plt.subplots()
            for i in range(USER_INP):
                self.ax.plot(self.x, f(self.x))
            self.ax.set_xlabel('X-axis')
            self.ax.set_ylabel('Y-axis')
            self.d1 = np.zeros(2)
            self.d2 = np.zeros(2)

            self.first_click = True
            self.cursor = Cursor(self.ax, horizOn=True, vertOn=True, color='black', linewidth=1)
            self.fig.canvas.mpl_connect('button_press_event', self.onclick)
            mplcursors.cursor(hover=True)
            plt.show()
        else:
            def quit(self):
                self.ROOT.destroy()

    def onclick(self, event):
        z1, r1 = event.xdata, event.ydata
        if self.first_click:
            self.first_click = False
            self.d1 = np.array((z1, r1))
        else:
            self.first_click = True
            self.d2 = np.array((z1, r1))
            distance = sqrt((((self.d1[0]) - (self.d2[0])) ** 2) + (((self.d1[1]) - (self.d2[1])) ** 2))
            delta = self.d2 - self.d1
            self.ax.lines[0].set_data(self.ax.lines[0].get_data() + delta.reshape(2,1))
            self.ax.relim()
            self.ax.autoscale_view()
            plt.draw()

dp = DistancePlot()

如果你只想左右移动,你可以使用set_xdata只改变x坐标。以下示例代码以给定的位移移动第二条曲线。如果要向左移动,则第二次单击应在第一次单击的左侧。

    def onclick(self, event):
        z1, r1 = event.xdata, event.ydata
        if self.first_click:
            self.first_click = False
            self.d1 = np.array((z1, r1))
        else:
            self.first_click = True
            self.d2 = np.array((z1, r1))
            delta_x = self.d1[0] - self.d2[0]
            self.ax.lines[1].set_xdata(self.ax.lines[1].get_xdata() + delta_x)
            self.ax.relim()
            self.ax.autoscale_view()
            plt.draw()