Luk*_*vis 1 python plot matplotlib legend python-3.x
假设我要制作一个包含五个项目的地块,并且只有空间来创建具有3列的图例(多列比这太宽了),例如
import matplotlib.pyplot as plt
f, a = plt.subplots()
for i in range(5):
a.plot(np.arange(10),np.random.rand(10),label='Item #%d'%i)
a.legend(ncol=3)
Run Code Online (Sandbox Code Playgroud)
底部行中的尾随两个条目向左对齐,在右侧留有很大的空白空间,这在美学上不是很令人满意。当您必须标记大量行时,这尤其成问题。
有什么方法可以使未填充行中的条目居中吗?
matplotlib图例是基于列的。您不能有跨越多个列的图例条目。也就是说,当然可以在图例中具有奇数行的“奇数”个条目居中,而在图例中具有偶数行的“奇数”个条目类似地“居中”。这可以通过在外部位置使用空艺术家来完成。
import matplotlib.pyplot as plt
import numpy as np
ncols = 3 # or 4
nlines = 7 # or 10
x = np.linspace(0,19)
f = lambda x,p: np.sin(x*p)
h = [plt.plot(x,f(x,i/10.), label="Line {}".format(i))[0] for i in range(nlines)]
h.insert(nlines//ncols, plt.plot([],[],color=(0,0,0,0), label=" ")[0])
plt.legend(handles=h, ncol=ncols, framealpha=1)
plt.show()
Run Code Online (Sandbox Code Playgroud)
如果列数为奇数,图例条目的数为偶数,反之亦然,则上述操作是不可能的。一种选择是使用两个不同的图例并将它们放置在另一个图例的下方,以使最后一行的条目看起来居中。
import matplotlib.pyplot as plt
import numpy as np
ncols = 3
nlines = 8
x = np.linspace(0,19)
f = lambda x,p: np.sin(x*p)
h = [plt.plot(x,f(x,i/10.), label="Line {}".format(i))[0] for i in range(nlines)]
kw = dict(framealpha=1, borderaxespad=0, bbox_to_anchor=(0.5,0.2), edgecolor="w")
leg1 = plt.legend(handles=h[:nlines//ncols*ncols], ncol=ncols, loc="lower center", **kw)
plt.gca().add_artist(leg1)
leg2 = plt.legend(handles=h[nlines//ncols*ncols:], ncol=nlines-nlines//ncols*ncols,
loc="upper center", **kw)
plt.show()
Run Code Online (Sandbox Code Playgroud)
这里的缺点是图例没有边框,并且两个图例都需要单独放置。为了克服这个问题,需要更深入地研究并使用图例的一些私有属性(警告,这些内容可能会因版本而异,恕不另行通知)。
然后,该想法可以是删除创建后的第二个图例,并将其_legend_handle_box放置在第一个图例中。
import matplotlib.pyplot as plt
import numpy as np
ncols = 3
nlines = 8
x = np.linspace(0,19)
f = lambda x,p: np.sin(x*p)
h = [plt.plot(x,f(x,i/10.), label="Line {}".format(i))[0] for i in range(nlines)]
kw = dict(framealpha=1, bbox_to_anchor=(0.5,0.2))
leg1 = plt.legend(handles=h[:nlines//ncols*ncols], ncol=ncols, loc="lower center", **kw)
plt.gca().add_artist(leg1)
leg2 = plt.legend(handles=h[nlines//ncols*ncols:], ncol=nlines-nlines//ncols*ncols)
leg2.remove()
leg1._legend_box._children.append(leg2._legend_handle_box)
leg1._legend_box.stale = True
plt.show()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
653 次 |
| 最近记录: |