logo
down
shadow

Matplotlib/tkinter: Event picking on legend when opening multiple windows


Matplotlib/tkinter: Event picking on legend when opening multiple windows

By : Zor Dravobox
Date : November 20 2020, 03:01 PM
may help you . This is probably mostly a design problem. I would recommend using a class for each plot window. The App class can then instantiate as many of those plot windows as you need, supplying the respective data as arguments. Each plot window manages the legend and events for itself.
code :
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import numpy as np

import Tkinter as tk

class Plotwindow():
    def __init__(self, master, data, legend):
        t = tk.Toplevel(master)
        # Frame for the plot
        plotFrame = tk.Frame(t)
        plotFrame.pack()

        f = plt.Figure()
        self.ax = f.add_subplot(111)
        self.canvas = FigureCanvasTkAgg(f,master=plotFrame)
        self.canvas.show()
        self.canvas.get_tk_widget().pack()
        self.canvas.mpl_connect('pick_event', self.onpick)

        # Plot
        lines = [0] * len(data)
        for j in range(len(data)):        
            X = range(0,len(data[j]))
            lines[j], = self.ax.plot(X,data[j],label=legend[j])
        leg = self.ax.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=3,ncol=2, borderaxespad=0.)
        self.lined = dict()
        for legline, origline in zip(leg.get_lines(), lines):
            legline.set_picker(5)  # 5 pts tolerance
            self.lined[legline] = origline

    def onpick(self, event):
        # on the pick event, find the orig line corresponding to the
        # legend proxy line, and toggle the visibility
        legline = event.artist
        origline = self.lined[legline]
        vis = not origline.get_visible()
        origline.set_visible(vis)
        # Change the alpha on the line in the legend so we can see what lines
        # have been toggled
        if vis:
            legline.set_alpha(1.0)
        else:
            legline.set_alpha(0.2)
        self.canvas.draw()

class App:
    def __init__(self,master):
        self.master = master
        # Frame for the training values
        buttonFrame = tk.Frame(master)
        buttonFrame.pack()

        self.buttonGenerate = tk.Button(master=buttonFrame,
                                        text='Train',
                                        command=self.train)
        self.buttonGenerate.grid(column=2,row=0)

    def train(self):

        aveCR = {0:{0:np.array([.582,1.081,1.507,1.872,2.180]),1:np.array([2.876,6.731,1.132,1.305,1.217])},
            1:{0:np.array([.582,1.081,1.507,1.872,2.180]),1:np.array([2.876,6.731,1.132,1.305,1.217])}}

        legend = {0: ['A', 'AB'], 1: ['A', 'AB']}

        self.windows = []
        for i in range(len(aveCR)):
            data = aveCR[i]
            self.windows.append(Plotwindow(self.master,data, legend[i]))


root = tk.Tk()
root.title("hem")
app = App(root)
root.mainloop()


Share : facebook icon twitter icon
python matplotlib errorbar legend picking

python matplotlib errorbar legend picking


By : Dedan
Date : March 29 2020, 07:55 AM
it helps some times I'm trying to code a legend picker for matplotlib errorbar plots similar to this example. I want to be able to click on the errorbars / datapoints in the legend to toggle their visibility in the axis. The problem is that the legend object returned by plt.legend() does not contain any data on the artists used in creating the legend. If I for eg. do: , This makes the markers pickable:
code :
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.legend_handler

from matplotlib.container import ErrorbarContainer

class re_order_errorbarHandler(matplotlib.legend_handler.HandlerErrorbar):
    """
    Sub-class the standard error-bar handler 
    """
    def create_artists(self, *args, **kwargs):
        #  call the parent class function
        a_list = matplotlib.legend_handler.HandlerErrorbar.create_artists(self, *args, **kwargs)
        # re-order the artist list, only the first artist is added to the
        # legend artist list, this is the one that corresponds to the markers
        a_list = a_list[-1:] + a_list[:-1]
        return a_list

my_handler_map = {ErrorbarContainer: re_order_errorbarHandler(numpoints=2)}

fig, ax = plt.subplots()
x = np.linspace(0,10,100)
y = np.sin(x) + np.random.rand(100)
yerr = np.random.rand(100)

erbpl1 = ax.errorbar(x, y, yerr=yerr, fmt='o', label='A')
erbpl2 = ax.errorbar(x, 0.02*y, yerr=yerr, fmt='o', label='B')

leg = ax.legend(handler_map=my_handler_map)

lines = [erbpl1, erbpl2]
lined = dict()
# not strictly sure about ordering, but 
for legline, origline in zip(leg.legendHandles, lines):
    legline.set_picker(5)  # 5 pts tolerance
    lined[legline] = origline


def onpick(event):
    # on the pick event, find the orig line corresponding to the
    # legend proxy line, and toggle the visibility
    legline = event.artist
    origline = lined[legline]
    for a in origline.get_children():
        vis = not a.get_visible()
        a.set_visible(vis)
    # Change the alpha on the line in the legend so we can see what lines
    # have been toggled
    if vis:
        legline.set_alpha(1.0)
    else:
        legline.set_alpha(0.2)
    fig.canvas.draw()

fig.canvas.mpl_connect('pick_event', onpick)
Tkinter/matplotlib multiple active windows on osx

Tkinter/matplotlib multiple active windows on osx


By : olcay akbay
Date : March 29 2020, 07:55 AM
like below fixes the issue I found a solution to this issue -- it seems matplotlib defaults to the TkAgg backend on Windows (I'm unsure whether this is a general Windows thing, or specific to whatever particular install is on the machine).
Adding the following lines to the top of the script forces the TkAgg backend and leads to the same behaviour on both machines.
code :
import matplotlib
matplotlib.use("TkAgg")
Matplotlib/tkinter: Event picking on the legend

Matplotlib/tkinter: Event picking on the legend


By : bronxton
Date : March 29 2020, 07:55 AM
should help you out In order to write your tkinter GUI in an object-oriented style, you need to make better use of the object-oriented structure. In particular:
1- Keep your code within the class's methods:
code :
# In your example, the following lines are outside any method
fig.canvas.mpl_connect('pick_event', onpick)

plt.show()
# Add self as the first argument in onpick()
def onpick(self, event):
    (...)
    # Now you can access self.canvas defined in __init__()
    self.canvas.draw()
import tkinter as tk
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
import numpy as np

t = np.arange(0.0, 0.2, 0.1)
y1 = 2*np.sin(2*np.pi*t)
y2 = 4*np.sin(2*np.pi*2*t)

class Main:
    def __init__(self, master):
        self.master = master
        master.title("A simple GUI")

        plotFrame = tk.Frame(master)
        plotFrame.pack()

        f = Figure(figsize=(5,4),dpi=100)
        self.ax = f.add_subplot(111)
        self.canvas = FigureCanvasTkAgg(f, master=plotFrame)
        self.canvas.show()
        self.canvas.get_tk_widget().pack()
        self.canvas.mpl_connect('pick_event', self.onpick)

        line1, = self.ax.plot(t, y1, lw=2, color='red', label='1 HZ')
        line2, = self.ax.plot(t, y2, lw=2, color='blue', label='2 HZ')
        leg = self.ax.legend(loc='upper left', fancybox=True, shadow=True)
        leg.get_frame().set_alpha(0.4)

        # we will set up a dict mapping legend line to orig line, and enable
        # picking on the legend line
        lines = [line1, line2]
        self.lined = dict()
        for legline, origline in zip(leg.get_lines(), lines):
            legline.set_picker(5)  # 5 pts tolerance
            self.lined[legline] = origline

    def onpick(self, event):
        # on the pick event, find the orig line corresponding to the
        # legend proxy line, and toggle the visibility
        legline = event.artist
        origline = self.lined[legline]
        vis = not origline.get_visible()
        origline.set_visible(vis)
        # Change the alpha on the line in the legend so we can see what lines
        # have been toggled
        if vis:
            legline.set_alpha(1.0)
        else:
            legline.set_alpha(0.2)
        self.canvas.draw()


root = tk.Tk()
my_gui = Main(root)
root.mainloop()
Draggable legend in matplotlib whilst having event picking functionality

Draggable legend in matplotlib whilst having event picking functionality


By : Justin
Date : March 29 2020, 07:55 AM
help you fix your problem Because you use a draggable legend, there is of course the possibility that a pick_event occurs on the legend; in fact all pick_event happening on one of the lines inside the legend also happen in the legend.
Now you would want to have the custom picking only happening if the picked artist is one of the lines from the dictionary. You can check for this to happen by querying if the event.artist is in the self.lined dictionary.
code :
    def onpick(self, event):
        if event.artist in self.lined.keys():
            legline = event.artist
            origline = self.lined[legline]
            vis = not origline.get_visible()
            origline.set_visible(vis)
            # Change the alpha on the line in the legend so we can see what lines
            # have been toggled
            if vis:
                legline.set_alpha(1.0)
            else:
                legline.set_alpha(0.2)
            self.canvas.draw_idle()
Tkinter - Multiple windows opening

Tkinter - Multiple windows opening


By : c.Porter.fc
Date : March 29 2020, 07:55 AM
will help you You just need make up a variable to keep track of if you have a note window open or not.
code :
tex.notes_open = False
def note_area():
    if tex.notes_open: 
        return # abort the function, notes already open
    else:
        tex.notes_open = True # set the flag for the next time
        # rest of your code
Related Posts Related Posts :
  • How to use an API that requires user's entry (Sentiment Analysis)
  • Django first app
  • Why is this regex code not working
  • Beautifulsoup - findAll not finding string when link is also in container
  • Python: any() to check if attribute in List of Objects matches a list
  • How do I "enrich" every record in a Pandas dataframe with an hour column?
  • Failing to open an Excel file with Python
  • Python function to modify string
  • Pandas DataFrame seems not to have "factorize" method
  • Row column operations in CSV
  • How to decrypt RSA encrypted file (via PHP and OpenSSL) with pyopenssl?
  • How can we use pandas to generate min, max, mean, median, ...as new columns for the dataframe?
  • Cython: creating an array throws "not allowed in a constant expression"
  • Different thing is shown in html
  • sublimetext3 event for program exit
  • Join contigous tokens if the token includes "@" char
  • transparent background in gif using Python Imageio
  • Enable autologin into flask app using active directory
  • Make a NxN array of 1x3 arrays of random numbers (python)
  • django how to use Max and Count on the same field in back-to-back annotations
  • Using the OR operator seems to only take the first of two conditions when used with np.where filter
  • Elegant Dataframe Operations in Pandas
  • Change metadata of pdf file with pypdf2
  • How can I animate a set of points with matplotlib?
  • error: (-215) count >= 0 && (depth == CV_32F || depth == CV_32S) in function arcLength
  • OpenStack KeyStone SSL Exception When Creating an Instance of KeyStone
  • pyspark: The system cannot find the path specified
  • How can I set path to load data from CSV file into PostgreSQL database in Docker container?
  • Summation in python dictionary
  • DRF 3.7.0 removed handling None in fields and broke my foreign key source fields. Is there a way around it?
  • Error with Padlen in signal.filtfilt in Python
  • Abstract matrix multiplication with variables
  • Reading binary data on bit level
  • How to replace multiple instances of a sub strings in a string using a for loop (in a function)?
  • py2neo cypher create several relations to central node in for loop
  • [python-3]TypeError: must be str, not int
  • How to exit/terminate a job earlier and handle the raised exception in apscheduler?
  • python, print intermediate values while loop
  • python to loop over yaml config
  • D3.js is not recognized by PyCharm
  • Access the regularization paths obtained from ElasticNetCV in sklearn
  • Pattern table to Pandas DataFrame
  • Get the earliest date from a column (Python Pandas) after csv.reader
  • Get SystemError: Parent module '' not loaded, cannot perform relative import when trying to import numpy in a Cython Ext
  • Bash or Python : Append and prepend a string recursively in all .tex files
  • Changing a certain index of boolean list of lists change others, too
  • complex dataframe filtering request on the last occurence of a value in Panda/Python [EDIT]
  • How to repeatedly get the contents of a Text widget every loop with tkinter?
  • How to call the tornado.queues message externally
  • How can I use regex in python so that characters not included are disallowed?
  • Discarding randmly scattered empty spaces in pandas data frame
  • Get sums grouped by date by same column filtered by 2 conditions
  • Element disappears when I add an {% include %} tag inside my for loop
  • Django Rest Framework with either a slug or a pk lookup field for the DetailAPIView
  • Flask doesn't stream on Lambda
  • Generate all permutations of fixed length where the elements come from two different sets
  • Making function for calculating distance
  • How to handle multiprocessing based on the limit of CPU's
  • Django - static files is not working
  • Remove x axis and y axis black lines with matplotlib
  • shadow
    Privacy Policy - Terms - Contact Us © voile276.org