问题描述
亲爱的
我编写了这段代码来计算图上两次鼠标点击之间的距离。现在,我正尝试根据计算出的偏移量将图向左或向右移动,以便两个图完全匹配。知道如何实现这一目标吗?我试着正常加减,但没有成功。
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,linewidth=1)
self.fig.canvas.mpl_connect('button_press_event',self.onclick)
mplcursors.cursor(hover=True)
plt.show()
def onclick(self,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 ",distance)
delta = self.d2 - self.d1
print("The delta between ",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 数组用于简化循环。 [2 3]
[1 3]
[1 2]
和 relim()
重新计算 x 和 y 限制以再次适合边距内的所有内容(如果预期位移较小,则可以跳过此步骤)。
autoscale_view()
如果您只想左右移动,可以使用 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()
仅更改 x 位置。以下示例代码以给定的位移移动第二条曲线。如果你想向左移动,第二次点击应该在第一次的左边。
set_xdata