Matplotlib 获取图例标记的坐标
Posted
技术标签:
【中文标题】Matplotlib 获取图例标记的坐标【英文标题】:Matplotlib getting coordinates of legend markers 【发布时间】:2021-09-17 15:33:31 【问题描述】:这是我第一次在这里提问。所以请告诉我是否有任何问题。
所以我正在尝试创建一个综合生成图表的数据集,以训练神经网络找到图表不同元素的边界框 - 图例框、图表标题、轴标签等。这就是我管理的部分去做。
接下来我需要创建一个从不同图例条目到其相应数据点的映射。我需要为围绕不同句柄和文本的边界框创建注释,如下所示:
我已尝试查看文档,但找不到任何相关功能。使用matplotlib.artist.getp()
研究图例的属性也让我一无所获。
fig, ax = plt.subplots(figsize=(12, 4))
x_vals = np.linspace(0, 5, 5)
y_vals = np.random.uniform(size=(5,))
ax.plot(x_vals, y_vals, label='line1')
ax.plot(x_vals, y_vals + np.random.randn(), label='line2')
leg = ax.legend()
ax.set_label('Label via method')
matplotlib.artist.getp(leg)
Output:
agg_filter = None
alpha = None
animated = False
bbox_to_anchor = TransformedBbox( Bbox(x0=0.125, y0=0.125, x1=0...
children = [<matplotlib.offsetbox.VPacker object at 0x7f3582d...
clip_box = None
clip_on = True
clip_path = None
contains = None
default_handler_map = <class 'matplotlib.container.StemContainer'>: <ma...
figure = Figure(864x288)
frame = FancyBboxPatch(640.55,203.64;60.625x33)
frame_on = True
gid = None
label =
legend_handler_map = <class 'matplotlib.container.StemContainer'>: <ma...
lines = [<matplotlib.lines.Line2D object at 0x7f35834f4400...
patches = <a list of 0 Patch objects>
path_effects = []
picker = None
rasterized = None
sketch_params = None
snap = None
texts = <a list of 2 Text objects>
title = Text(0,0,'None')
transform = IdentityTransform()
transformed_clip_path_and_affine = (None, None)
url = None
visible = True
window_extent = Bbox(x0=640.5500000000001, y0=203.64, x1=701.17500...
zorder = 5
任何帮助将不胜感激。请告诉我是否需要任何澄清。谢谢
【问题讨论】:
【参考方案1】:我花了整整 30 分钟的时间试图弄清楚一些事情。我确信有一个更简单的方法,但这是我整理的一些东西,希望对你有所帮助
import matplotlib.pyplot as plt; plt.ion()
from matplotlib.patches import Rectangle as rect
fig, ax = plt.subplots()
ax.plot([0,1],[4,6],label='test')
leg = ax.legend(edgecolor='w', loc='upper left')
leg.get_frame().set_alpha(0)
line = leg.get_lines()[0]
plt.draw()
plt.pause(0.001)
#all of this is based on pixel coordinates in the figure
(lx0, ly0, lx1, ly1) = (leg.get_window_extent().x0,
leg.get_window_extent().y0,
leg.get_window_extent().x1,
leg.get_window_extent().y1)
(mx0, my0, mx1, my1) = (line.get_window_extent(fig).x0,
line.get_window_extent(fig).y0,
line.get_window_extent(fig).x1,
line.get_window_extent(fig).y1)
(ax0, ay0, ax1, ay1) = (ax.get_window_extent().x0,
ax.get_window_extent().y0,
ax.get_window_extent().x1,
ax.get_window_extent().y1)
#convert pixel coords to graphical coords
x0, x1 = ax.get_xlim()
y0, y1 = ax.get_ylim()
ratex = (x1-x0) / (ax1-ax0)
ratey = (y1-y0) / (ay1-ay0)
newx0 = (mx0 - ax0) * ratex + x0
newx1 = (mx1 - ax0) * ratex + x0
newy0 = (my0 - ay0) * ratey + y0 - 0.05
newy1 = (my1 - ay0) * ratey + y0 + 0.05
#box around legend marker
ax.add_patch(rect((newx0, newy0), newy1-newy0, newx1-newx0, edgecolor='k', alpha=0.5, facecolor='w'))
#convert pixel coords to graphical coords
tx0 = mx1
tx1 = lx1
ty0 = ly0
ty1 = ly1
newx0 = (tx0 - ax0) * ratex + x0
newx1 = (tx1 - ax0) * ratex + x0
newy0 = (ty0 - ay0) * ratey + y0
newy1 = (ty1 - ay0) * ratey + y0
#box around legend txt
ax.add_patch(rect((newx0, newy0), newy1-newy0, newx1-newx0, edgecolor='k', alpha=0.5, facecolor='w'))
这会产生以下情节:
我不是 100% 确定为什么这些框是关闭的,但是您可以修改它以使其以某种方式工作...您也可以使用它来获取图例条目的坐标,并从这些坐标绘制一个向量到坐标在相应的数据线上
【讨论】:
非常感谢最初的指导。对于此答案中提到的每个元素,我能够使用leg._legend_handle_box.get_children()
后跟get_window_extent()
获得更精确的坐标:***.com/a/44072076/13430696
lmao 什么任务..很高兴你想通了以上是关于Matplotlib 获取图例标记的坐标的主要内容,如果未能解决你的问题,请参考以下文章