我有一个GUI,允许用户使用形状(例如,以X,Y和直径D为中心的圆,其中有N个点,其中使用输入框输入X,Y,D和N)来创建点集。
从生成的点集中,绘制点并计算2D重心并将其绘制出来。为了绘制质心,我使用4个楔形图绘制了一个4象限的黑白圆圈。
数据图很好(我用一个空白数据集初始化了一个散点图,然后在用户每次生成输入时向其添加数据)。虽然我有点茫然,但要绘制质心。我可以根据给定的数据集计算并绘制质心,但是我不确定执行更新的最“有效”方法。
我应该初始化一个“空白”质心符号,然后以某种方式更新楔形的中心(不确定我的质心函数如何做到这一点),类似于用于整个数据集的方法,还是应该删除并重新-每次生成更多数据时都要创建质心(我该怎么做)?
省略生成所有数据点的代码,仅绘制质心即可得到:
import tkinter as tk
from tkinter import ttk
import numpy as np
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import matplotlib
from matplotlib.figure import Figure
from matplotlib.patches import Wedge, Circle
matplotlib.use("TkAgg")
class MainGUI(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.title('Title')
self.geometry('750x500')
self.nb = ttk.Notebook(self)
self.nb.grid(row=0, column=0, columnspan=5, rowspan=4, sticky='NESW')
self.tab2 = ttk.Frame(self.nb)
self.nb.add(self.tab2, text='Tab2')
self.rowconfigure(0, weight=1)
self.columnconfigure(0, weight=1)
tab2_r = 8
tab2_c = 4
for i in range(tab2_r):
self.tab2.rowconfigure(i, weight=1)
for i in range(tab2_c):
self.tab2.columnconfigure(i, weight=1)
self.makeWidgets()
self.initializePlot()
def makeWidgets(self):
self.Labels = []
self.Entries = []
self.labText = [('X Location:'), ('Y Location:')]
self.xGrid = 1
self.yGrid = int(np.ceil(len(self.labText) / self.xGrid))
i = 0
for j in range(0, self.xGrid + 1, 2):
for k in range(self.yGrid):
if(i == len(self.labText)):
break
else:
self.label = tk.Label(self.tab2, text=self.labText[i])
self.label.grid(column=j, row=k + 8, sticky='SW')
self.Labels.append(self.label)
self.entry = tk.Entry(self.tab2)
self.entry.insert(0, '0.0000')
self.entry.grid(column=j + 1, row=k + 8, sticky='NS')
self.Entries.append(self.entry)
i += 1
self.addBtn = tk.Button(self.tab2, text='Add Entry', command=self.plotstuff)
self.addBtn.grid(column=self.xGrid + 1, row=self.yGrid + 9, sticky='NSEW')
def initializePlot(self):
self.fig = Figure(figsize=(1, 1), dpi=100)
self.ptrnFig = self.fig.add_subplot(111)
self.ptrnFig.axis('equal')
self.ptrnFig.axis([-5, 5, -5, 5])
self.ptrnFig.spines['left'].set_position('zero')
self.ptrnFig.spines['bottom'].set_position('zero')
self.ptrnFig.grid(True)
self.canvas = FigureCanvasTkAgg(self.fig, self.tab2)
self.canvas.draw()
self.canvas.get_tk_widget().grid(column=0, row=0, columnspan=4, rowspan=5, sticky='NSEW')
self.scat = self.ptrnFig.scatter([], [], c="b", marker="o") # Used to plot full dataset
def plotstuff(self):
# self.scat.set_offsets(dataset) <---- Used to plot full dataset, updated each time data entered
self.points = np.array([float(self.Entries[0].get()), float(self.Entries[1].get())], ndmin=2)
self.cog = self.plotCOG((self.points[0, 0], self.points[0, 1]), 0.1, angle=0, ax=self.ptrnFig)
self.canvas.draw_idle()
def plotCOG(self, center, radius, angle=0, ax=None, colors=('w', 'k'), **kwargs):
if ax is None:
ax = plt.gca()
# Some code here to delete old COG?
theta1, theta2, theta3, theta4 = angle, angle + 90, angle + 180, angle + 270
w1 = Wedge(center, radius, theta1, theta2, fc=colors[0], ec='k', **kwargs)
w2 = Wedge(center, radius, theta2, theta3, fc=colors[1], ec='k', **kwargs)
w3 = Wedge(center, radius, theta3, theta4, fc=colors[0], ec='k', **kwargs)
w4 = Wedge(center, radius, theta4, theta1, fc=colors[1], ec='k', **kwargs)
for wedge in [w1, w2, w3, w4]:
ax.add_artist(wedge)
def main():
MainGUI().mainloop()
if __name__ == '__main__':
main()
我尝试了多种形式的ax.remove(),例如
for wedge in [w1, w2, w3, w4]:
wedge.remove()
在plotCOG函数的开始(尝试检查楔形是否已经绘制之后),但似乎找不到任何有效的方法。
感谢您的帮助。
答案 0 :(得分:0)
该方法似乎是正确的。唯一的问题是您没有参考旧的楔块。因此,您可以将它们存储在某个地方,以便以后使用。
def initializePlot(self):
# ....
self.wedges = []
def plotCOG(self, center, radius, angle=0, ax=None, colors=('w', 'k'), **kwargs):
ax = ax or plt.gca()
for wedge in self.wedges:
wedge.remove()
# ..
w1 = Wedge(..)
w2 = Wedge(..)
w3 = Wedge(..)
w4 = Wedge(..)
self.wedges = [w1, w2, w3, w4]
for wedge in self.wedges:
ax.add_artist(wedge)