手动图例中的自定义标记边缘样式

时间:2017-08-20 20:55:04

标签: python matplotlib

我想手动创建一个图表的图例,它不会直接引用图中的任何数据,例如:

import matplotlib.pyplot as plt
from matplotlib.lines import Line2D

plt.plot([0, 1], [3, 2])
line = Line2D([], [], label='abc', color='red', linewidth=1.5, marker='o',
              markerfacecolor='yellow', markeredgewidth=1.5, markersize=16)
plt.legend(handles=[line], numpoints=1)
plt.show()

Resulting plot

这很有效,除非因为我找不到设置标记边缘样式(即实线,虚线,点线等)的方法。 Line2D没有markeredgestyle属性或类似属性,而设置linestyle似乎不会影响标记边缘样式。 有解决方法吗?

我想到了一些方法,但我不确定它们有多可行:

  • 使用与Line2D完全不同的东西。它需要在图例中显示,具有与Line2D相同的格式选项,以及额外的标记边缘样式。不确定这样的课程是否存在
  • 创建一个派生自Line2D的自定义类,并自行实现该标记边缘样式
  • 在绘图本身中创建数据,然后将其从那里删除,同时以某种方式将其保留在图例中。不确定是否存在允许我在实际图表中执行此操作的类。请注意,它必须包含标记和行。我能想到的最近的事情是使用散点图作为标记并绘制线条,但这会显示两个图例条目(除非有办法将它们合并为一个)

理想情况下,线条样式和标记边缘样式可能会有所不同,但如果有一种方法可以更改标记边缘样式,包括覆盖线条样式,我也会接受它。

我正在使用matplotlib 1.5.3。

2 个答案:

答案 0 :(得分:3)

您可以使用具有虚线边缘的特殊标记符号,例如marker=ur'$\u25CC$' (完整的STIX symbol table)。

import matplotlib.pyplot as plt
from matplotlib.lines import Line2D

plt.plot([0, 1], [3, 2])
line = Line2D([], [], label='abc', color='red', linewidth=1.5, marker=ur'$\u25CC$',
              markeredgecolor='indigo', markeredgewidth=0.5, markersize=16)
plt.legend(handles=[line], numpoints=1)
plt.show()

enter image description here

然而,这不能填补。

另一方面,scatter绘图没有任何连接线,因此linestyle的{​​{1}}确实会影响标记边缘。 因此,您可以组合scatterLine2D,其中该行没有标记并构成背景线,并且分散负责标记。

scatter

enter image description here

答案 1 :(得分:0)

我找到了一种基于我的第三种方法和this answer的解决方法。基本上,如果为它们分配单个标签,则可以在图例中组合句柄。因此,您可以从Line2D对象创建行,然后从散点函数创建标记,后者允许您指定您可能需要的任何标记格式:

import matplotlib.pyplot as plt
from matplotlib.lines import Line2D

plt.plot([0, 1], [3, 2])
line = Line2D([], [], color='red', linewidth=1.5)

marker = plt.scatter([], [], linewidth=2, edgecolor='black', s=75,
                     c='yellow', linestyle='dotted')
marker.remove()  # The scatter plot had no data, so no markers would have shown up anyway

plt.legend(handles=((line, marker),), labels=('abc',), numpoints=1, scatterpoints=1)
plt.show()

Resulting chart