2017-02-20 7 views
3

Ich möchte oft einen Punkt entlang der Kurve markieren matplotlib mit einer Handlung zu machen, die wie folgt aussieht: Basic PlotMatplotlib Geben Punkt auf X- und Y-Achse

Der folgende Code den Plot

erstellen wurde verwendet
import numpy as np 
import matplotlib.pyplot as plt 
import seaborn as sns 

y = np.array([0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100])/100. 
x = 100. - np.array([ 
    99.79,98.96,98.65,98.39,98.13,97.88,97.61,97.33,97.01,96.65,96.21, 
    95.72,95.16,94.46,93.52,92.31,90.66,88.48,84.04,79.34,19.32]) 
ax = plt.subplot(111) 
line = plt.plot(x,y) 


def highlight_point(ax,line,point,linestyle=':'): 
    c = line.get_color() 
    xmin = ax.get_xlim()[0] 
    ymin = ax.get_ylim()[0] 

    ax.plot([xmin,point[0]],[point[1],point[1]],color=c,linestyle=linestyle) 
    ax.plot([point[0],point[0]],[ymin,point[1]],color=c,linestyle=linestyle) 

plt.xlim([0,85]) 
plt.ylim([0,1]) 
highlight_point(ax,line[0],[x[10],y[10]]) 
plt.show() 

Die obige Methode schlägt fehl, wenn xlim und ylim nicht eingegeben werden können oder wenn der Abbildung später eine andere Grafik hinzugefügt wurde. Ich möchte eine Kombination von axhline oder hlines, wo ich die linke/untere Seite des Diagramms auf einen bestimmten mathematischen Punkt angeben kann.

+0

Es könnte in der Tat die Möglichkeit, eine Art von Blended zu verwenden Transformation an die Punkte, die die Linien bilden. Da jedoch nur eine der vier Koordinaten im Achsensystem existiert, während die anderen drei im Datensystem leben, habe ich keine Ahnung, wie ich das umsetzen soll. – ImportanceOfBeingErnest

+0

Was bedeutet "Ich könnte dies mit kleinen Gitterpunkten angreifen"? – ImportanceOfBeingErnest

Antwort

2

Ein Weg zu gehen könnte sein, die Zeilen jedes Mal zu aktualisieren, wenn die Zeichenfläche neu gezeichnet wird. Zu diesem Zweck könnten wir eine Klasse PointMarkers mit einer Update-Methode erstellen, die mit dem Listener draw_event verbunden ist. Auf diese Weise werden die Linien nicht nur aktualisiert, wenn nach der Erstellung der Markierungslinien Punkte hinzugefügt werden, sondern auch wenn die Größe der Leinwand geändert oder verschoben wird.

import numpy as np 
import matplotlib.pyplot as plt 
import seaborn as sns 

class PointMarker(): 
    def __init__(self, ax, point, **kwargs): 
     self.ax = ax 
     self.point = point 
     if "line" in kwargs: 
      self.c = kwargs.get("line").get_color() 
     else: 
      self.c = kwargs.get("color", "b") 
     self.ls=kwargs.get("linestyle", ':') 
     self.vline, = self.ax.plot([],[],color=self.c,linestyle=self.ls) 
     self.hline, = self.ax.plot([],[],color=self.c,linestyle=self.ls) 
     self.draw() 

    def draw(self): 
     xmin = ax.get_xlim()[0] 
     ymin = ax.get_ylim()[0] 
     self.vline.set_data([self.point[0], self.point[0]], [ymin,self.point[1]]) 
     self.hline.set_data([xmin, self.point[0]], [self.point[1], self.point[1]]) 

class PointMarkers(): 
    pointmarkers = [] 
    def add(self,ax, point, **kwargs): 
     pm = PointMarker(ax, point, **kwargs) 
     self.pointmarkers.append(pm) 
    def update(self, event=None): 
     for pm in self.pointmarkers: 
      pm.draw() 

x = np.arange(1,17) 
y = np.log(x) 
ax = plt.subplot(111) 
line = plt.plot(x,y) 

# register the markers 
p = PointMarkers() 
p.add(ax,[x[5],y[5]], line=line[0]) 
p.add(ax,[x[12],y[12]], color="purple", linestyle="-.") 
# connect event listener 
cid = plt.gcf().canvas.mpl_connect("draw_event", p.update) 

#testing: draw some new points or change axis limits 
plt.plot([5,11],[-0.5,0.6]) 
#plt.xlim([0,85]) 
#plt.ylim([0,1]) 

plt.show() 

enter image description here

Für Einsparung würde die neu gezeichnet werden müssen manuell direkt vor dem Befehl speichern durchgeführt werden, wie

plt.gcf().canvas.draw() 
plt.savefig(...) 
Verwandte Themen