Matplotlib自定义图例显示正方形而不是矩形
这是我试图改变从矩形一个barplot传说方:Matplotlib自定义图例显示正方形而不是矩形
import matplotlib.patches as patches
rect1 = patches.Rectangle((0,0),1,1,facecolor='#FF605E')
rect2 = patches.Rectangle((0,0),1,1,facecolor='#64B2DF')
plt.legend((rect1, rect2), ('2016', '2015'))
但是,当我绘制这个,我仍然看到矩形,而不是正方形:
我如何能做到这一点有什么建议?
我试图通过@ImportanceOfBeingErnest和@furas提供两种解决方案,这里的结果:
@ ImportanceOfBeingErnest的解决方案是最容易做的:
plt.rcParams['legend.handlelength'] = 1
plt.rcParams['legend.handleheight'] = 1.125
下面是结果:
我最后的代码如下所示:
plt.legend((df.columns[1], df.columns[0]), handlelength=1, handleheight=1) # the df.columns = the legend text
@ furas的解决方案产生这个,我不知道为什么文本是从矩形渐行渐远,但我可以肯定的差距能以某种方式被改变:
Matplotlib提供rcParams
legend.handlelength : 2. # the length of the legend lines in fraction of fontsize
legend.handleheight : 0.7 # the height of the legend handle in fraction of fontsize
你可以设置呼叫内plt.legend()
plt.legend(handlelength=1, handleheight=1)
或使用rcParams在脚本的开头
import matplotlib
matplotlib.rcParams['legend.handlelength'] = 1
matplotlib.rcParams['legend.handleheight'] = 1
不幸的是提供平等handlelength=1, handleheight=1
不会给一个完美的rectange。看来handlelength=1, handleheight=1.125
会完成这项工作,但这可能取决于正在使用的字体。
另一种方法是,如果要使用代理艺术家,可以使用plot/scatter方法中的方形标记。
bar1 = plt.plot([], marker="s", markersize=15, linestyle="", label="2015")
并将其提供给图例legend(handles=[bar1])
。使用这种方法需要设置matplotlib.rcParams['legend.numpoints'] = 1
,否则两个标记将出现在图例中。
下面是两种方法
import matplotlib.pyplot as plt
plt.rcParams['legend.handlelength'] = 1
plt.rcParams['legend.handleheight'] = 1.125
plt.rcParams['legend.numpoints'] = 1
fig, ax = plt.subplots(ncols=2, figsize=(5,2.5))
# Method 1: Set the handlesizes already in the rcParams
ax[0].set_title("Setting handlesize")
ax[0].bar([0,2], [6,3], width=0.7, color="#a30e73", label="2015", align="center")
ax[0].bar([1,3], [3,2], width=0.7, color="#0943a8", label="2016", align="center")
ax[0].legend()
# Method 2: use proxy markers. (Needs legend.numpoints to be 1)
ax[1].set_title("Proxy markers")
ax[1].bar([0,2], [6,3], width=0.7, color="#a30e73", align="center")
ax[1].bar([1,3], [3,2], width=0.7, color="#0943a8", align="center")
b1, =ax[1].plot([], marker="s", markersize=15, linestyle="", color="#a30e73", label="2015")
b2, =ax[1].plot([], marker="s", markersize=15, linestyle="", color="#0943a8", label="2016")
ax[1].legend(handles=[b1, b2])
[a.set_xticks([0,1,2,3]) for a in ax]
plt.show()
一个完整的例子生产
看来他们改变它很久以前的事 - 现在有些元素不能被直接使用在传说中。
现在需要handler
: Implementing a custom legend handler
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib.legend_handler import HandlerPatch
# --- handlers ---
class HandlerRect(HandlerPatch):
def create_artists(self, legend, orig_handle,
xdescent, ydescent, width, height,
fontsize, trans):
x = width//2
y = 0
w = h = 10
# create
p = patches.Rectangle(xy=(x, y), width=w, height=h)
# update with data from oryginal object
self.update_prop(p, orig_handle, legend)
# move xy to legend
p.set_transform(trans)
return [p]
class HandlerCircle(HandlerPatch):
def create_artists(self, legend, orig_handle,
xdescent, ydescent, width, height,
fontsize, trans):
r = 5
x = r + width//2
y = height//2
# create
p = patches.Circle(xy=(x, y), radius=r)
# update with data from oryginal object
self.update_prop(p, orig_handle, legend)
# move xy to legend
p.set_transform(trans)
return [p]
# --- main ---
rect = patches.Rectangle((0,0), 1, 1, facecolor='#FF605E')
circ = patches.Circle((0,0), 1, facecolor='#64B2DF')
plt.legend((rect, circ), ('2016', '2015'),
handler_map={
patches.Rectangle: HandlerRect(),
patches.Circle: HandlerCircle(),
})
plt.show()
传奇储备到位矩形,此方法不改变它,有这么多的空的空间。
Concverning的最后一个点的位置:在解决方案从@furas它使用传统的handler_map补丁改变是二次。然而,与矩形(因此更宽)的补丁相比,文本的填充保持不变。默认情况下,这个填充是'0.8',但你可以像使用'plt.rcParams ['legend.handletextpad'] = 0'这样使用rcParams来设置它来减少间距。在这种情况下,你可能会设置一些负数,“-0.8”可能是不错的选择。 – ImportanceOfBeingErnest