为图例中的点设置固定大小 [英] Setting a fixed size for points in legend

查看:83
本文介绍了为图例中的点设置固定大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在绘制一些散点图,我想将图例中的点的大小设置为固定的,相等的值.

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:

  1. 更改maplotlib代码
  2. 将转换添加到表示图像中点的PathCollection对象中.转换(缩放)必须考虑原始大小.
  1. Change the maplotlib code
  2. 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 a plot, which changes the marker scaling (hence the sqrt) 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆