为图例中的点设置固定大小 [英] Setting a fixed size for points in legend
问题描述
我正在绘制一些散点图,我想将图例中的点的大小设置为固定的,相等的值.
I'm making some scatter plots and I want to set the size of the points in the legend to a fixed, equal value.
现在我有这个了
import matplotlib.pyplot as plt
import numpy as np
def rand_data():
return np.random.uniform(low=0., high=1., size=(100,))
# Generate data.
x1, y1 = [rand_data() for i in range(2)]
x2, y2 = [rand_data() for i in range(2)]
plt.figure()
plt.scatter(x1, y1, marker='o', label='first', s=20., c='b')
plt.scatter(x2, y2, marker='o', label='second', s=35., c='r')
# Plot legend.
plt.legend(loc="lower left", markerscale=2., scatterpoints=1, fontsize=10)
plt.show()
会产生以下结果:
图例中点的大小已缩放,但不相同.如何在不影响scatter
图中大小的情况下将图例中点的大小固定为相等的值?
The sizes of the points in the legend are scaled but not the same. How can I fix the sizes of the points in the legend to an equal value without affecting the sizes in the scatter
plot?
推荐答案
我研究了matplotlib
的源代码.坏消息是,似乎没有任何简单的方法可以在图例中设置相等大小的点.散点图尤其困难(错误:请参见下面的更新).基本上有两种选择:
I had a look into the source code of matplotlib
. Bad news is that there does not seem to be any simple way of setting equal sizes of points in the legend. It is especially difficult with scatter plots (wrong: see the update below). There are essentially two alternatives:
- 更改
maplotlib
代码 - 将转换添加到表示图像中点的
PathCollection
对象中.转换(缩放)必须考虑原始大小.
- Change the
maplotlib
code - Add a transform into the
PathCollection
objects representing the dots in the image. The transform (scaling) has to take the original size into account.
尽管#1似乎更容易,但这两个都不是很有趣. scatter
图在这方面特别具有挑战性.
Neither of these is very much fun, though #1 seems to be easier. The scatter
plots are especially challenging in this respect.
但是,我有一个骇客,它可能可以满足您的要求:
However, I have a hack which does probably what you want:
import matplotlib.pyplot as plt
import numpy as np
def rand_data():
return np.random.uniform(low=0., high=1., size=(100,))
# Generate data.
x1, y1 = [rand_data() for i in range(2)]
x2, y2 = [rand_data() for i in range(2)]
plt.figure()
plt.plot(x1, y1, 'o', label='first', markersize=np.sqrt(20.), c='b')
plt.plot(x2, y2, 'o', label='second', markersize=np.sqrt(35.), c='r')
# Plot legend.
lgnd = plt.legend(loc="lower left", numpoints=1, fontsize=10)
#change the marker size manually for both lines
lgnd.legendHandles[0]._legmarker.set_markersize(6)
lgnd.legendHandles[1]._legmarker.set_markersize(6)
plt.show()
这给出了:
似乎正是您想要的.
更改:
-
scatter
更改为plot
,这会更改标记的缩放比例(因此是sqrt
),并且无法使用更改的标记大小(如果需要的话) - 图例中两个标记的标记大小已手动更改为6点
scatter
changed into aplot
, which changes the marker scaling (hence thesqrt
) and makes it impossible to use changing marker size (if that was intended)- the marker size changed manually to be 6 points for both markers in the legend
如您所见,它利用了隐藏的下划线属性(_legmarker
),并且很丑陋.在matplotlib
中的任何更新中,它可能会崩溃.
As you can see, this utilizes hidden underscore properties (_legmarker
) and is bug-ugly. It may break down at any update in matplotlib
.
更新
哈,我找到了.更好的技巧:
Haa, I found it. A better hack:
import matplotlib.pyplot as plt
import numpy as np
def rand_data():
return np.random.uniform(low=0., high=1., size=(100,))
# Generate data.
x1, y1 = [rand_data() for i in range(2)]
x2, y2 = [rand_data() for i in range(2)]
plt.figure()
plt.scatter(x1, y1, marker='o', label='first', s=20., c='b')
plt.scatter(x2, y2, marker='o', label='second', s=35., c='r')
# Plot legend.
lgnd = plt.legend(loc="lower left", scatterpoints=1, fontsize=10)
lgnd.legendHandles[0]._sizes = [30]
lgnd.legendHandles[1]._sizes = [30]
plt.show()
现在,_sizes
(另一个下划线属性)可以解决问题.即使这是很hack,也无需接触源代码.但是现在您可以使用scatter
提供的所有内容.
Now the _sizes
(another underscore property) does the trick. No need to touch the source, even though this is quite a hack. But now you can use everything scatter
offers.
这篇关于为图例中的点设置固定大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!