matplotlib 为图例组合合并两个修补程序

lqfhib0f  于 2023-10-24  发布在  其他
关注(0)|答案(4)|浏览(188)

我尝试用置信带绘制一些数据。我为每个数据流绘制两个图:plotfill_between。我希望图例看起来与图相似,其中每个条目都有一个框(置信区域的颜色),中间有一条较暗的实线。
到目前为止,我已经能够使用补丁创建矩形图例键,但我不知道如何实现中心线。我尝试使用阴影,但没有控制的位置,厚度,或颜色。
我最初的想法是尝试合并两个补丁(Patch和2DLine);然而,它还没有工作。有更好的方法吗?我的MWE和当前的数字如下所示。

import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0,1,11)
y = np.linspace(0,1,11)

plt.plot(x, y, c='r')
plt.fill_between(x, y-0.2, y+0.2, color='r', alpha=0.5)
p = mpatches.Patch(color='r', alpha=0.5, linewidth=0)

plt.legend((p,), ('Entry',))

ygya80vv

ygya80vv1#

这个解决方案是从CrazyArm的评论中借来的,可以在这里找到:Matplotlib, legend with multiple different markers with one label。显然,你可以制作一个句柄列表,只分配一个标签,它神奇地结合了两个句柄/艺术家。

import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0,1,11)
y = np.linspace(0,1,11)

p1, = plt.plot(x, y, c='r')  # notice the comma!
plt.fill_between(x, y-0.2, y+0.2, color='r', alpha=0.5)
p2 = mpatches.Patch(color='r', alpha=0.5, linewidth=0)

plt.legend(((p1,p2),), ('Entry',))

relj7zay

relj7zay2#

对于那些想进一步推动这个主题的人

我有一个非常类似的问题,不同的是,我希望图例表示一个自定义形状(也是用plotfill_between创建的),由一个带虚线的矩形填充(因为形状有这种模式)。示例如下图所示:

我找到的解决方案是按照Matplotlib Legend指南实现一个自定义图例处理程序。
特别是,我实现了一个类,它定义了一个legend_artist方法,允许您通过向handlebox添加补丁来尽可能多地自定义处理程序(或者这就是我所理解的)。
我发布了一个矩形而不是斑点形状的MWE(这需要大量的空间,并会模糊信息)。

import matplotlib.patches as mpatches
import matplotlib.pyplot as plt

class DashedFilledRectangleHandler:
    def legend_artist(self, legend, orig_handle, fontsize, handlebox):
        x0, y0 = handlebox.xdescent, handlebox.ydescent
        width, height = handlebox.width, handlebox.height
        patch_fill = mpatches.Rectangle((x0, y0), width, height, facecolor='tab:blue', linestyle='', alpha=0.1,
                                        transform=handlebox.get_transform())
        patch_line = mpatches.Rectangle((x0, y0), width, height, fill=False, edgecolor='tab:blue', linestyle='--',
                                        transform=handlebox.get_transform())
        handlebox.add_artist(patch_line)
        handlebox.add_artist(patch_fill)
        return patch_line

fig, ax = plt.subplots()

rectangle_fill = ax.add_patch(mpatches.Rectangle((0, 0), 2, 1, facecolor='tab:blue', edgecolor='tab:blue', linestyle='',
                                                 alpha=0.1))
rectangle_line = ax.add_patch(mpatches.Rectangle((0, 0), 2, 1, fill=False, edgecolor='tab:blue', linestyle='--',
                                                 lw=3))

ax.legend([rectangle_fill], ['Dashed filled rectangle handler'],
          handler_map={rectangle_fill: DashedFilledRectangleHandler()})
ax.set_xlim([-1, 3])
ax.set_ylim([-1, 2])
plt.show()
vkc1a9a2

vkc1a9a23#

从你的代码开始,
这是我能给你的最接近的。可能有一种方法可以以你想要的方式创建补丁,但我对这个也有点陌生,我所能做的就是建立适当的传奇:

import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0,1,11)
y = np.linspace(0,1,11)

fig = plt.figure()
ax = fig.add_subplot(111)
plt.plot(x, y, c='r',label='Entry')
plt.fill_between(x, y-0.2, y+0.2, color='r', alpha=0.5)
p_handle = [mpatches.Patch(color='r', alpha=0.5, linewidth=0)]
p_label = [u'Entry Confidence Interval']
handle, label = ax.get_legend_handles_labels()
handles=handle+p_handle
labels=label+p_label
plt.legend(handles,labels,bbox_to_anchor=(0. ,1.02 ,1.,0.3),loc=8,
           ncol=5,mode='expand',borderaxespad=0,prop={'size':9},numpoints=1)

plt.show()

从我所能告诉你的,你将不得不创建一个“艺术家”对象,适合你正在寻找的设计,我找不到一个方法来做。
希望这有助于好运,我有兴趣,如果有更深入的方式以及。

xuo3flqw

xuo3flqw4#

我有“类似”的问题。我能够实现以下感谢这个问题。

fig = pylab.figure()
figlegend = pylab.figure(figsize=(3,2))
ax = fig.add_subplot(111)
point1 = ax.scatter(range(3), range(1,4), 250, marker=ur'$\u2640$', label = 'S', edgecolor = 'green')
point2 = ax.scatter(range(3), range(2,5), 250, marker=ur'$\u2640$', label = 'I', edgecolor = 'red')
point3 = ax.scatter(range(1,4), range(3),  250, marker=ur'$\u2642$', label = 'S', edgecolor = 'green')
point4 = ax.scatter(range(2,5), range(3), 250, marker=ur'$\u2642$', label = 'I', edgecolor = 'red')
figlegend.legend(((point1, point3), (point2, point4)), ('S','I'), 'center',  scatterpoints = 1, handlelength = 1)
figlegend.show()
pylab.show()

然而,我的两个(金星和火星)标记在图例中重叠。我试着用手柄长度来玩,但似乎没有帮助。任何建议或评论都将是有帮助的。

相关问题