我经常想要使用matplotlib
突出显示曲线上的一个点,以制作如下情节:
以下代码用于创建情节
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 :(得分: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()
对于保存,需要在保存命令之前直接手动执行重绘,如
plt.gcf().canvas.draw()
plt.savefig(...)