How to receive a callback if clicked somewhere but on a figure? - python

I wrote a code that allows to click inside an entry widget and activate a function that returns the mouse coordinates if clicked on a figure. The problem is that I want to click somewhere else than the figure or entry widget to deactivate the function but I don't know how to do that.
What I tried so far is binding (with bind) a callback function that deactivates the select_marker function to master (what obviously makes no sense) or to a certain Frame (didn't help). I couldn't find any solution by browsing SO or the web.
import sys
if sys.version_info[0] < 3:
import Tkinter as Tk
else:
import tkinter as Tk
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import numpy as np
class Application():
def __init__(self, master):
self.master = master
master.iconify
self.entry_frame = Tk.Frame(master)
self.entry_frame.pack(side=Tk.TOP, fill=Tk.BOTH, expand=0)
self.m1_label = Tk.Label(self.entry_frame, text='Mouse Coordinates: ')
self.m1_label.pack(side=Tk.LEFT)
self.m1_entry = Tk.Entry(self.entry_frame, width=10)
self.m1_entry.pack(side=Tk.LEFT)
self.m1_entry.bind('<Button-1>', lambda e:self.callback(1))
self.image_frame = Tk.Frame(master)
self.image_frame.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
self.image_frame.bind('<Button-1>', lambda e:self.callback(0)) # something like this
self.fig = Figure()
self.ax = self.fig.add_subplot(111)
self.ax.set_aspect('equal')
self.canvas = FigureCanvasTkAgg(self.fig, self.image_frame)
self.canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
self.canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
self.widget_active = 0
self.fig.canvas.mpl_connect('button_press_event', self.select_marker)
def callback(self, state):
self.widget_active = state
print(state)
def select_marker(self, event):
if self.widget_active == 1:
if event.button == 1:
x = np.round(event.xdata,2)
y = np.round(event.ydata,2)
print(x,y)
self.m1_entry.delete(0,'end')
self.m1_entry.insert(0,(str(x)+', '+str(y)))
else:
pass
if self.widget_active == 0:
pass
root = Tk.Tk()
Application(root)
root.mainloop()
I would really appreciate if someone knows a way to get a callback if clicked somewhere except the entry widget or the figure. Thanks a lot!

Related

Embedding a MatPlotLib Graph in Tkinter [.grid method], and Customizing MatPlotLib's Navigation Toolbar

I've been having problems with embedding my MatPlotLib Graph in Tkinter, and after doing some searching on Google, and the MatPlotLib website, the best I could get was the standard method:
import tkinter
from matplotlib.backends.backend_tkagg import (
FigureCanvasTkAgg, NavigationToolbar2Tk)
fig = Figure(figsize=(5, 4), dpi=100)
canvas = FigureCanvasTkAgg(fig, master=root)
canvas.draw()
canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1)
toolbar = NavigationToolbar2Tk(canvas, root) toolbar.update()
canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1)
Now if I try to replace the packing layout with a .grid (and remove the .pack() parameters), I get a bunch of errors, and no matter how many Google searches I have tried, all of the methods of embedding a MatPlotLib graph in Tkinter are only using the pack method. Can someone help me out with this? I want to embed the graph, but using the grid method, as the rest of the layout of my GUI application is .grid layout.
Another problem I'm having with the navigation toolbar in Tkinter is the fact that the navigation toolbar can apparently be customized (At least according to SentDex [5:18]). He doesn't seem to go over how I can do this, which makes it difficult for me, because I'm not very happy with MatPlotLib's buttons (They look very archaic and outdated).
Can someone please help me out with this? When I only put the graph in, it seems to work just fine, but I get issues when trying to put in the Navigation Toolbar with the graph as well. Any help on this would be appreciated. Thanks!
Here is a simple plot and navigation toolbar inside tkinter window using grid geometry manager only.
import tkinter as tk
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk)
window = tk.Tk()
btn = tk.Label(window, text='A simple plot')
btn.grid(row=0, column=0, padx=20, pady=10)
x = ['Col A', 'Col B', 'Col C']
y = [50, 20, 80]
fig = plt.figure(figsize=(4, 5))
plt.bar(x=x, height=y)
# You can make your x axis labels vertical using the rotation
plt.xticks(x, rotation=90)
# specify the window as master
canvas = FigureCanvasTkAgg(fig, master=window)
canvas.draw()
canvas.get_tk_widget().grid(row=1, column=0, ipadx=40, ipady=20)
# navigation toolbar
toolbarFrame = tk.Frame(master=window)
toolbarFrame.grid(row=2,column=0)
toolbar = NavigationToolbar2Tk(canvas, toolbarFrame)
window.mainloop()
Output GUI
I have not worked on customizing the navigation toolbar so I haven't included any solution for that part. But I'll look into it surely and update you if I find something useful. Hope you find this helpful.
I managed to get a simple app to control a matplotlib graph with window resizing.
I haven't used the navigation bar feature so that might be an addition to this framework
import tkinter as tk
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
from google.cloud import bigquery
import os, json, sys
from time import time
import pandas as pd
class SliderGraph:
def __init__(self, master):
self.master = master
# with open(self.resource_path(config_file)) as fp:
# self.config = json.load(fp)
# os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = self.resource_path(creds_file)
# self.projectID = self.config['projectID']
# self.datasetID = self.config['datasetID']
# last_used_freq = self.config['last_used_frequency']
# last_used_delta = self.config['last_used_delta']
self.bounds = 1
self.frame = tk.Frame(master)
self.fig = Figure()
row = 0
self.ax = self.fig.add_subplot(111)
self.ax.set_xlabel("Run Numbers")
self.ax.set_ylabel("UDD")
self.ax.set_ylim([-self.bounds,self.bounds])
self.canvas = FigureCanvasTkAgg(self.fig, master=master) # , width=win_width, height=(win_height-50))
self.canvas.draw()
self.canvas.get_tk_widget().grid(row=row, columnspan=2, sticky='nsew')
row+=1
self.table_label = tk.Label(master, text="Enter BigQuery Table Name")
self.table_label.grid(row=row, column=0)
# row += 1
self.table_name = tk.Entry(master)
# self.table_name.insert(0,self.config['last_used_table'])
self.table_name.grid(row=row, column=1, sticky='ew')
row += 1
self.get_table_button = tk.Button(master, text="Get Table Data and Plot", command=self.plot_data)
self.get_table_button.grid(row=row, columnspan=2)
row += 1
self.frequency_slider = tk.Scale(master, from_=400, to=4500, orient=tk.HORIZONTAL, command=self.update_plot)
# self.frequency_slider.set(last_used_freq)
self.frequency_slider.grid(row=row,columnspan=2, sticky="nsew")
row += 1
self.frequency_entry = tk.Entry(master)
# self.frequency_entry.insert(0,last_used_freq)
self.frequency_entry.grid(row=row, columnspan=2)
row += 1
self.delta_slider = tk.Scale(master, from_=-500, to=500, orient=tk.HORIZONTAL, command=self.update_plot)
# self.delta_slider.set(last_used_delta)
self.delta_slider.grid(row=row, columnspan=2, sticky="ensw")
row += 1
self.delta_entry = tk.Entry(master)
# self.delta_entry.insert(0, last_used_delta)
self.delta_entry.grid(row=row, columnspan=2)
row += 1
self.get_table_button = tk.Button(master, text="Autoscale", command=self.autoscale)
self.get_table_button.grid(row=row,columnspan=2)
row += 1
tk.Grid.columnconfigure(master, 0, weight=1)
tk.Grid.columnconfigure(master, 1, weight=1)
tk.Grid.rowconfigure(master, 0, weight=5)
for x in range(1,row):
tk.Grid.rowconfigure(master, x, weight=0)
master.protocol('WM_DELETE_WINDOW', self.close)
self.df = None
self.frequency_list = []
self.series = None
self.elapsed = time()*1000
def plot_data(self):
self.ax.clear()
self.client = bigquery.Client(project=self.projectID)
self.tableID = f"`{self.datasetID}.{self.table_name.get()}`"
QUERY = (
f"SELECT * EXCEPT (testCount,elapsed_run_time_ms_,moleculeValue,onboardTemp1,onboardTemp2,temp,tempControl,\
logamp, txrx,timestamp) FROM {self.tableID} ORDER BY runCount ASC;"
)
# query_job = self.client.query(QUERY)
# rows = query_job.result()
self.df = pd.read_gbq(QUERY,self.projectID)
for col in self.df.columns:
if 'runCount' in col:
continue
self.frequency_list.append(int(col.replace('_','')))
self.frequency_slider.configure(from_=min(self.frequency_list),to=max(self.frequency_list))
self.delta_slider.configure(from_=-max(self.frequency_list),to=max(self.frequency_list))
freq = f'_{self.frequency_slider.get()}'
freq2 = f'_{self.frequency_slider.get() + self.delta_slider.get()}'
self.series = self.df[freq] - self.df[freq2]
self.series.plot(ax=self.ax)
self.ax.set_ylim([-self.bounds,self.bounds])
self.fig.canvas.draw()
self.fig.canvas.flush_events()
pass
def update_plot(self, newslider):
try:
self.ax.clear()
freq = f'_{self.frequency_slider.get()}'
freq2 = f'_{self.frequency_slider.get() + self.delta_slider.get()}'
self.series = self.df[freq] - self.df[freq2]
self.series.plot(ax=self.ax)
zero = self.series.mean()
self.ax.set_ylim([zero-self.bounds, zero+self.bounds])
self.fig.canvas.draw()
self.fig.canvas.flush_events()
# self.master.update_idletasks()
if ((time()*1000)-self.elapsed > 100):
self.elapsed = time()*1000
self.frequency_entry.delete(0,'end')
self.frequency_entry.insert(0,freq.replace('_',''))
self.delta_entry.delete(0,'end')
self.delta_entry.insert(0,self.delta_slider.get())
except:
pass
def play_runs(self):
pass
def autoscale(self):
self.ax.clear()
self.series.plot(ax=self.ax)
self.ax.relim()
self.ax.autoscale()
zero = self.series.mean()
self.bounds = self.series.max() - self.series.min()
self.ax.set_ylim([zero-self.bounds,zero+self.bounds])
self.fig.canvas.draw()
self.fig.canvas.flush_events()
def close(self):
self.master.destroy()
if __name__=="__main__":
root = tk.Tk()
slider_fig = SliderGraph(root)
root.mainloop()

How to plot circle with scalable radius?

I wrote a few lines of code that should draw a circle where I can adjust its radius by using a slider. Unfortunately there must be some major mistakes in my code but as I am a beginner it is hard to find them. Can anyone give me some advise to make it work?
A tiny GUI has been set up using tkinter including a Tk.Scale and a canvas. The function drawCircle creates a Circle artist. The essential part is connecting the slider with the function changeRadius but thats where I don't know what to do. See my code below...
import sys
if sys.version_info[0] < 3:
import Tkinter as Tk
else:
import tkinter as Tk
from matplotlib.figure import Figure
from matplotlib import pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
class PlotCircle():
def __init__(self, master):
self.master = master
master.iconify
self.f_rad = 2 # initial value
self.frame = Tk.Frame(master)
self.frame.pack(side=Tk.TOP, fill=Tk.BOTH, expand=0)
self.radius_label = Tk.Label(self.frame, text='Radius: ')
self.radius_label.pack(side=Tk.LEFT)
self.scroll_radius = Tk.Scale(self.frame, from_=1.0, to=3.0, resolution=0.05,
orient=Tk.HORIZONTAL, command=lambda:self.changeRadius(self.circle))
self.scroll_radius.set(2.0)
self.scroll_radius.pack(side=Tk.LEFT)
self.image_frame = Tk.Frame(master)
self.image_frame.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
self.fig = Figure()
self.ax = self.fig.add_subplot(111)
self.ax.set_aspect('equal')
self.canvas = FigureCanvasTkAgg(self.fig, self.image_frame)
self.canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
self.canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
def drawCircle(self):
self.circle = plt.Circle((0.5, 0.5), self.f_rad*0.1, color='#F97306', fill=False)
self.ax.add_artist(self.circle)
self.fig.canvas.draw()
def changeRadius(self, circ):
self.f_rad = float(self.scroll_radius.get())
print(self.f_rad)
circ.set_radius(self.f_rad)
self.fig.canvas.draw()
root = Tk.Tk()
PlotCircle(root)
root.mainloop()
By executing this code I get the following error:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\p.schulmeyer\AppData\Local\Continuum\anaconda3\lib\tkinter__init__.py", line 1705, in call
return self.func(*args)
TypeError: lambda() takes 0 positional arguments but 1 was given
I also tried using lambda e: or not using lambda at all but nothing helped. I guess my mistake must be something more fundamental. I really appreciate any help. Thanks!
You need to do the following changes to make your script work.
Ensure that you call drawCircle in constructor, hence self.circle is set
command needs a function that can accept a param
def __init__(self, master):
...
self.scroll_radius = Tk.Scale(self.frame, from_=1.0, to=3.0, resolution=0.05,
orient=Tk.HORIZONTAL, command=lambda x:self.changeRadius(x))
...
self.drawCircle()
def changeRadius(self, new_radius):
self.circle.set_radius(float(new_radius)*0.1)
self.fig.canvas.draw()

Overlay graph in tkinter

I am making an embeded matplotlib graph GUI program.
I want to make overlaid graphs in upper graph window when users click the "Update" button.
But, There is no response when I click "Update" button.
I am using Spyder Python 3.6 Version.
Below is what I wrote.
import matplotlib.pyplot as plt
import csv
import numpy as np
import tkinter as tk
from tkinter import ttk
import matplotlib as plt
plt.use("TkAgg")
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
from matplotlib import style
class Analysis_app(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
tk.Tk.wm_title(self, "SIM Analyser")
right_f = tk.Frame(self)
right_f.pack(side=tk.RIGHT)
self.entry1 = ttk.Entry(right_f).pack()
self.entry2 = ttk.Entry(right_f).pack()
self.entry3 = ttk.Entry(right_f).pack()
self.entry4 = ttk.Entry(right_f).pack()
self.entry5 = ttk.Entry(right_f).pack()
Button1 = ttk.Button(right_f, text='Update', command=self.plot).pack(side=tk.BOTTOM)
self.left_f = tk.Frame(self)
self.left_f.pack(side=tk.LEFT)
f = Figure(figsize=(10,6), dpi=100)
self.upplot = f.add_subplot(211)
self.botplot = f.add_subplot(212)
a =self.upplot
a.clear()
a.plot([1,2,3],[1,2,3])
canvas = FigureCanvasTkAgg(f, self)
canvas.show()
canvas.get_tk_widget().pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True)
toolbar = NavigationToolbar2TkAgg(canvas, self)
toolbar.update()
canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
self.mainloop()
def plot(self):
a =self.upplot
a.clear()
a.plot([1,2,3],[5,2,5])
You get no response because the canvas is not redrawn after changing the content of the plot.
The solution is to replace canvas = FigureCanvasTkAgg(f, self) by self.canvas = FigureCanvasTkAgg(f, self) so that you can redraw the canvas in self.plot:
def plot(self):
a = self.upplot
a.clear()
a.plot([1,2,3],[5,2,5])
self.canvas.draw_idle()
And then you should see the change after clicking on the update button.

Tkinter window to be shut and control flow to be returned automatically

I have an external script that calls the drawWorld() function of this class.
I want the drawing to be shown for 1-2 seconds and then to close and the control to return to the main script.
I can manage to let the window disappear with the line
root.after(1000, lambda: root.destroy())
but I cannot return the flow to the main script.
I tried
root.after(1000, lambda: root.quit())
but it doesn't work.
This is my code for the Tkinter class:
from Tkinter import Tk, Canvas, Frame, BOTH
class World(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.parent.title("CliffWorld")
self.pack(fill=BOTH, expand=1)
canvas = Canvas(self)
canvas.create_rectangle(4, 4, 31, 31,
outline="#f11", fill="#1f1", width=1)
canvas.pack(fill=BOTH, expand=1)
def drawWorld():
root = Tk()
ex = World(root)
root.geometry("330x220+300+300")
root.after(1000, lambda: root.destroy())
root.after(1000, lambda: root.quit())
root.mainloop()
In a comment to your question you wrote that your main program is just this:
import tkWorld
tkWorld.drawWorld()
print "end"
When I use that in a program, and use your example code (after fixing the indentation), it works fine. I see the window appear for one second, it goes away, and I send "end" printed on the console.
It works no matter whether the lambda calls root.quit() or root.destroy().
from Tkinter import Tk, Canvas, Frame, BOTH
class World(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.parent.title("CliffWorld")
self.pack(fill=BOTH, expand=1)
canvas = Canvas(self)
canvas.create_rectangle(4, 4, 31, 31,
outline="#f11", fill="#1f1", width=1)
canvas.pack(fill=BOTH, expand=1)
def drawWorld():
root = Tk()
ex = World(root)
root.geometry("330x220+300+300")
root.after(1000, lambda: root.destroy())
root.after(1000, lambda: root.quit())
root.mainloop()
if __name__ == "__main__":
import tkWorld
tkWorld.drawWorld()
print "end"

Matplotlib event and replotting

I want to be able to create a plot, press one button or another depending on what the plot shows, and then plot the following object. However, I am having some trouble wih it: it seems I can't make it "wait" untill a button is pressed. Also, I am wondering if it would be possible to pass some parameters to the press_event, like a path to save something.
Here is the scheme of the program in case it helps. Thanks a lot in advance!
# event definition
def ontype(event):
if event.key == '1':
do stuff 1
plt.savefig(...)
plt.clf()
elif event.key == '2':
do stuff 2
plt.savefig(...)
plt.clf()
elif event.key == '3':
do stuff 3
plt.savefig(...)
plt.clf()
# main program
...stuff
create figure
plt.show()
plt.gcf().canvas.mpl_connect('key_press_event',ontype)
You must call plt.gcf().canvas.mpl_connect('key_press_event',ontype) before plt.show(). In non-interactive mode, the execution waits at plt.show() until the plot-window is closed.
import pylab as plt
# event definition
def ontype(event):
if event.key == '1':
print "1"
elif event.key == '2':
print "2"
elif event.key == '3':
print "3"
# main program
plt.plot([1,6,3,8,7])
plt.gcf().canvas.mpl_connect('key_press_event',ontype)
plt.show()
Alternatively, replace in your sample plt.show() to plt.ion(), which enables interactive mode. But it depends on your specific needs which solution you prefer.
Edit
New example using Tkinter
import random
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
try:
import Tkinter as Tk
except ImportError:
import tkinter as Tk
import tkMessageBox
class PlotClassifier(Tk.Tk):
def __init__(self, plot_generator, arguments, classes, classification_callback, *args, **kwargs):
Tk.Tk.__init__(self, *args, **kwargs)
self.title("Plot classifier, working on %i plots" % len(arguments))
#self.label = Tk.Label(text="Plot classifier, working on %i plots" % len(arguments))
#self.label.pack(padx=10, pady=10)
self._plot_generator = plot_generator
self._arguments = arguments
self._classes = [str(x) for x in classes]
self._classification_callback = classification_callback
self._setup_gui()
def _setup_gui(self):
#self.columnconfigure(0, minsize=100, weight=2)
#self.columnconfigure(1, minsize=500, weight=8)
f = Figure()
self._ax = f.add_subplot(111)
buttons_frame = Tk.Frame(self)
buttons_frame.pack(side=Tk.TOP, fill=Tk.BOTH, expand=True)
buttons_class = []
for i, cls in enumerate(self._classes):
buttons_class.append(Tk.Button(master=buttons_frame, text=cls,
command=lambda x=i: self.button_classification_callback(self._current_args, x)))
buttons_class[-1].pack(side=Tk.LEFT)
button_quit = Tk.Button(master=buttons_frame, text='Quit', command=self.destroy)
button_quit.pack(side=Tk.RIGHT) #.grid(row=0,column=0)
self._canvas = FigureCanvasTkAgg(f, master=self)
self._canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1) #.grid(row=0, column=1, rowspan=3) #
self._canvas.show()
toolbar = NavigationToolbar2TkAgg( self._canvas, self )
toolbar.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1) #.grid(row=3, column=1) #
toolbar.update()
def button_classification_callback(self, args, class_idx):
self._classification_callback(args, self._classes[class_idx])
self.classify_next_plot()
def classify_next_plot(self):
try:
self._current_args = self._arguments.pop(0)
self._ax.cla()
self._plot_generator(self._ax, *self._current_args)
self._canvas.draw()
except IndexError:
tkMessageBox.showinfo("Complete!", "All plots were classified")
self.destroy()
def create_plot(ax, factor):
ax.plot([(i*factor) % 11 for i in range(100)])
def announce_classification(arguments, class_):
print arguments, class_
if __name__ == "__main__":
classes = ["Class %i"%i for i in range(1, 6)]
arguments_for_plot = [[random.randint(1,10)] for x in range(10)]
root = PlotClassifier(create_plot, arguments_for_plot, classes, classification_callback=announce_classification)
root.after(50, root.classify_next_plot)
root.mainloop()
The class takes as arguments:
* a callback to create each plot
* a list of lists of arguments for each plot to generate (might each be an empty list)
* a list of class-names. For each class, a button is created
* a callback that is called each time a classification has been performed
Any feedback would be appreciated.
*EDIT 2 *
For your comment, a slightly modified version. For every iteration of the loop, a new window is opened
import random
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
try:
import Tkinter as Tk
except ImportError:
import tkinter as Tk
import tkMessageBox
class PlotClassifier(Tk.Tk):
def __init__(self, plot_generator, arguments, classes, *args, **kwargs):
Tk.Tk.__init__(self, *args, **kwargs)
self.title("Plot classifier")
self._plot_generator = plot_generator
self._arguments = arguments
self._classes = [str(x) for x in classes]
self.class_ = None
self._setup_gui()
def _setup_gui(self):
#self.columnconfigure(0, minsize=100, weight=2)
#self.columnconfigure(1, minsize=500, weight=8)
f = Figure()
self._ax = f.add_subplot(111)
buttons_frame = Tk.Frame(self)
buttons_frame.pack(side=Tk.TOP, fill=Tk.X, expand=True)
buttons_class = []
for i, cls in enumerate(self._classes):
buttons_class.append(Tk.Button(master=buttons_frame, text=cls,
command=lambda x=i: self.button_classification_callback(x)))
buttons_class[-1].pack(side=Tk.LEFT)
button_quit = Tk.Button(master=buttons_frame, text='Quit', command=self.destroy)
button_quit.pack(side=Tk.RIGHT) #.grid(row=0,column=0)
self._canvas = FigureCanvasTkAgg(f, master=self)
self._canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1) #.grid(row=0, column=1, rowspan=3) #
self._canvas.show()
toolbar = NavigationToolbar2TkAgg( self._canvas, self )
toolbar.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1) #.grid(row=3, column=1) #
toolbar.update()
def button_classification_callback(self, class_idx):
self.class_ = self._classes[class_idx]
self.destroy()
def classify_plot(self):
self._ax.cla()
self._plot_generator(self._ax, *self._arguments)
self._canvas.draw()
self.mainloop()
return self.class_
def create_plot(ax, factor):
ax.plot([(i*factor) % 11 for i in range(100)])
if __name__ == "__main__":
classes = ["Class %i"%i for i in range(1, 6)]
arguments_for_plot = [[random.randint(1,10)] for x in range(10)]
for args in arguments_for_plot:
classifier = PlotClassifier(create_plot, args, classes)
class_ = classifier.classify_plot()
print args, class_
if class_ is None:
break
This helps to fit into your own for-loop, but you still have to give a function to do the plotting after the GUI was created.

Categories