增加matplotlib中图例线的线宽

And*_*nca 51 python matplotlib legend

我知道如果我改变一条线的线宽,它会在图例中自动更新.但是我想在不影响绘图的情况下更改图例线宽.

Bre*_*ood 64

这是一个如何做到的简单示例:

import numpy as np
import matplotlib.pyplot as plt

# make some data
x = np.linspace(0, 2*np.pi)
y1 = np.sin(x)
y2 = np.cos(x)

# plot sin(x) and cos(x)
p1 = plt.plot(x, y1, 'b-', linewidth=1.0)
p2 = plt.plot(x, y2, 'r-', linewidth=1.0)

# make a legend for both plots
leg = plt.legend([p1, p2], ['sin(x)', 'cos(x)'], loc=1)

# set the linewidth of each legend object
for legobj in leg.legendHandles:
    legobj.set_linewidth(2.0)

plt.show()
Run Code Online (Sandbox Code Playgroud)


jdh*_*hao 6

@Brendan Wood的方法使用所提供的api pyplot。在matplotlib中,首选使用 axis的面向对象样式。以下是使用axes方法的实现方法。

import numpy as np
import matplotlib.pyplot as plt

# make some data
x = np.linspace(0, 2*np.pi)
y1 = np.sin(x)
y2 = np.cos(x)

fig, ax = plt.subplots()
ax.plot(x, y1, linewidth=1.0, label='sin(x)')
ax.plot(x, y2, linewidth=1.0, label='cos(x)')
leg = ax.legend()

for line in leg.get_lines():
    line.set_linewidth(4.0)

plt.show()
Run Code Online (Sandbox Code Playgroud)

产生的图如下所示, 在此处输入图片说明


Imp*_*est 5

默认情况下,图例包含行本身。因此,更改画布中线条的线宽也会更改图例中的线条(反之亦然,因为它们本质上是相同的对象)。

一种可能的解决方案是使用画布中艺术家的副本并仅更改副本的线宽。

import numpy as np
import matplotlib.pyplot as plt
import copy

x = np.linspace(0, 2*np.pi)
y1 = np.sin(x)
y2 = np.cos(x)
fig = plt.figure()
ax  = fig.add_subplot(111)
ax.plot(x, y1, c='b', label='y1',linewidth=1.0)
ax.plot(x, y2, c='r', label='y2')

# obtain the handles and labels from the figure
handles, labels = ax.get_legend_handles_labels()
# copy the handles
handles = [copy.copy(ha) for ha in handles ]
# set the linewidths to the copies
[ha.set_linewidth(7) for ha in handles ]
# put the copies into the legend
leg = plt.legend(handles=handles, labels=labels)

plt.savefig('leg_example')
plt.show()
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

另一种选择是使用 ahandler_map和更新功能。这在某种程度上是自动的,指定处理程序映射将自动使图例中的任何线宽 7 磅。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.legend_handler import HandlerLine2D

x = np.linspace(0, 2*np.pi)
y1 = np.sin(x)
y2 = np.cos(x)
fig = plt.figure()
ax  = fig.add_subplot(111)
ax.plot(x, y1, c='b', label='y1',linewidth=1.0)
ax.plot(x, y2, c='r', label='y2')

linewidth=7
def update(handle, orig):
    handle.update_from(orig)
    handle.set_linewidth(7)

plt.legend(handler_map={plt.Line2D : HandlerLine2D(update_func=update)})

plt.show()
Run Code Online (Sandbox Code Playgroud)

结果和上面一样。