2015-07-14 4 views
7

Ich benutze pyplot um ein Liniendiagramm von bis zu 30 Zeilen anzuzeigen. Ich möchte eine Möglichkeit hinzufügen, um einzelne Linien im Diagramm schnell ein- und auszublenden. Pyplot hat ein Menü, in dem Sie Linieneigenschaften bearbeiten können, um die Farbe oder den Stil zu ändern, aber es ist ziemlich klobig, wenn Sie Linien ausblenden möchten, um die zu isolieren, die Sie interessiert. Idealerweise würde ich gerne Checkboxen in der Legende verwenden Linien anzeigen und ausblenden. (Ähnlich wie das Anzeigen und Ausblenden von Layern in Bildeditoren wie Paint.Net) Ich bin mir nicht sicher, ob das mit pyplot möglich ist, also bin ich offen für andere Module, solange sie leicht zu verteilen sind.Verstecken von Linien nach dem Anzeigen einer Pyplot Figur

+0

Sie Ihre Frage zu bereichern, können Sie diese Art von Verhalten finden (auswählen, welche Linien auf die Show Grafik, indem Sie auf die Legende Untertitel) in der Gnuplot, zB, http://gnuplot.sourceforge.net/demo_svg_5.0/simple.html Ich bin mir nicht sicher, wie bereit Sie von pyplot zu einem anderen Werkzeug (gnuplot) wechseln , aber wenn du mit Python Schritt halten und gnuplot verwenden willst, gibt es eine 'gnuplot.py' Schnittstelle. – David

+0

Dies ist genau die Funktionalität, nach der ich suche. Ich werde es untersuchen und sehen, wie gut es mit meinem Programm funktioniert. – sommerjj

+0

Update: Ich gebe gnuplot auf. Es funktionierte nicht gut für mich. – sommerjj

Antwort

13

Wenn Sie möchten, können Sie einen Rückruf an die Legende anschließen, die Linien beim Anklicken anzeigt/versteckt. Es gibt ein einfaches Beispiel hier: http://matplotlib.org/examples/event_handling/legend_picking.html

Hier ist ein "schicker" Beispiel, das funktionieren sollte, ohne die Beziehung der Zeilen und Legendenmarker manuell angeben zu müssen (hat auch ein paar mehr Funktionen).

import numpy as np 
import matplotlib.pyplot as plt 

def main(): 
    x = np.arange(10) 
    fig, ax = plt.subplots() 
    for i in range(1, 31): 
     ax.plot(x, i * x, label=r'$y={}x$'.format(i)) 

    ax.legend(loc='upper left', bbox_to_anchor=(1.05, 1), 
       ncol=2, borderaxespad=0) 
    fig.subplots_adjust(right=0.55) 
    fig.suptitle('Right-click to hide all\nMiddle-click to show all', 
       va='top', size='large') 

    interactive_legend().show() 

def interactive_legend(ax=None): 
    if ax is None: 
     ax = plt.gca() 
    if ax.legend_ is None: 
     ax.legend() 

    return InteractiveLegend(ax.legend_) 

class InteractiveLegend(object): 
    def __init__(self, legend): 
     self.legend = legend 
     self.fig = legend.axes.figure 

     self.lookup_artist, self.lookup_handle = self._build_lookups(legend) 
     self._setup_connections() 

     self.update() 

    def _setup_connections(self): 
     for artist in self.legend.texts + self.legend.legendHandles: 
      artist.set_picker(10) # 10 points tolerance 

     self.fig.canvas.mpl_connect('pick_event', self.on_pick) 
     self.fig.canvas.mpl_connect('button_press_event', self.on_click) 

    def _build_lookups(self, legend): 
     labels = [t.get_text() for t in legend.texts] 
     handles = legend.legendHandles 
     label2handle = dict(zip(labels, handles)) 
     handle2text = dict(zip(handles, legend.texts)) 

     lookup_artist = {} 
     lookup_handle = {} 
     for artist in legend.axes.get_children(): 
      if artist.get_label() in labels: 
       handle = label2handle[artist.get_label()] 
       lookup_handle[artist] = handle 
       lookup_artist[handle] = artist 
       lookup_artist[handle2text[handle]] = artist 

     lookup_handle.update(zip(handles, handles)) 
     lookup_handle.update(zip(legend.texts, handles)) 

     return lookup_artist, lookup_handle 

    def on_pick(self, event): 
     handle = event.artist 
     if handle in self.lookup_artist: 
      artist = self.lookup_artist[handle] 
      artist.set_visible(not artist.get_visible()) 
      self.update() 

    def on_click(self, event): 
     if event.button == 3: 
      visible = False 
     elif event.button == 2: 
      visible = True 
     else: 
      return 

     for artist in self.lookup_artist.values(): 
      artist.set_visible(visible) 
     self.update() 

    def update(self): 
     for artist in self.lookup_artist.values(): 
      handle = self.lookup_handle[artist] 
      if artist.get_visible(): 
       handle.set_visible(True) 
      else: 
       handle.set_visible(False) 
     self.fig.canvas.draw() 

    def show(self): 
     plt.show() 

if __name__ == '__main__': 
    main() 

Damit können Sie auf Legendenelemente klicken, um die entsprechenden Interpreten ein-/auszuschalten. Zum Beispiel können Sie von diesem gehen:

enter image description here

Um dies:

enter image description here

+1

Das ist genau die Funktionalität, nach der ich suche! Ich habe versucht, seltsame Workarounds zu finden, wie die Verwendung einer Tkinter-GUI mit Checkboxen, die den Graphen jedes Mal neu zeichnen, wenn eine Änderung an den Selektionen vorgenommen wurde. Das ist viel einfacher – sommerjj

+0

Aber es zeigt immer noch die Legenden der versteckten Plots! – hbaromega

Verwandte Themen