Matplotlib指示X轴和Y轴上的点

5
我经常想用matplotlib来突出展示曲线上的一个点,制作一个看起来像这样的图形: Basic Plot 以下代码用于创建该图:
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()

当没有输入xlimylim或之后添加另一个图时,上述方法会失败。我希望使用axhlinehlines的组合来指定绘图的左/底部到某个数学点。


实际上,可能有一种使用混合变换来处理构成直线的点的选项。然而,由于其中仅有4个坐标中的1个存在于坐标系中,而其他三个存在于数据系统中,因此我不知道如何实现这个选项。 - ImportanceOfBeingErnest
“我可以使用次要网格点进行攻击”是什么意思? - ImportanceOfBeingErnest
1个回答

5
一种方法是每次重新绘制画布时更新线条。为此,我们可以创建一个名为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(...)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接