2017-02-20 19 views
3

Я часто хочу, чтобы выделить точку вдоль кривой с помощью matplotlib, чтобы сделать сюжет, который выглядит как: Basic PlotMatplotlib Укажите точку на X и Y оси

Следующий код был использован для создания сюжета

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() 

Вышеуказанный метод терпит неудачу, когда xlim и ylim не введены, или если другой рисунок был добавлен к рисунку позже. Мне нужна комбинация axhline или hlines, где я могу указать левое/нижнее значение графика для определенной математической точки.

+0

Там на самом деле может быть вариантом, чтобы использовать какое-то смешанное преобразование точки, составляющие линии. Однако, поскольку только одна из 4 координат живет в системе осей, в то время как остальные три живут в системе данных, я понятия не имею, как это реализовать. – ImportanceOfBeingErnest

+0

Что означает «Я мог бы атаковать это, используя небольшие точки сетки»? – ImportanceOfBeingErnest

ответ

2

Способ перехода может состоять в том, чтобы обновлять строки каждый раз, когда холст перерисовывается. С этой целью мы могли бы создать класс PointMarkers с методом обновления, который подключен к слушателю draw_event. Таким образом, строки будут обновляться не только после добавления точек после создания маркерных линий, но и при изменении размера или панорамирования холста.

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

Для экономии, перекройка необходимо будет выполняться вручную непосредственно перед командой сохранения, как

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

 Смежные вопросы

  • Нет связанных вопросов^_^