在 Matplotlib 中选择标记大小 [英] Choosing marker size in Matplotlib
问题描述
我正在matplotlib中使用正方形标记绘制散点图,如下所示:
I am doing a scatter plot with square marker in matplotlib like this one:
.
我想实现这样的目标:
这意味着我必须调整标记大小和图形大小/比例,以便标记之间没有空白.每个索引单元也应该有一个标记(x 和 y 都是整数)所以如果 y 从 60 到 100,应该有y 方向有 40 个标记.目前我正在手动调整它.知道实现这一目标的最佳方法是什么吗?
Which means I have to adjust the marker size and the figure size/ratio in such a way that there are no white space between markers. Also there should be a marker per index unit (x and y are both integers) so if y goes from 60 to 100, there should be 40 markers in y direction. At the moment I am tuning it manually. Any idea on what is the best way to achieve this?
推荐答案
我发现了两种解决方法:
I found two ways to go about this:
第一个基于 这个答案.基本上,您可以确定相邻数据点之间的像素数,并使用它来设置标记大小. scatter
中的标记大小以面积给出.
The first is based on this answer. Basically, you determine the number of pixels between the adjacent data-points and use it to set the marker size. The marker size in scatter
is given as area.
fig = plt.figure()
ax = fig.add_subplot(111, aspect='equal')
# initialize a plot to determine the distance between the data points in pixel:
x = [1, 2, 3, 4, 2, 3, 3]
y = [0, 0, 0, 0, 1, 1, 2]
s = 0.0
points = ax.scatter(x,y,s=s,marker='s')
ax.axis([min(x)-1., max(x)+1., min(y)-1., max(y)+1.])
# retrieve the pixel information:
xy_pixels = ax.transData.transform(np.vstack([x,y]).T)
xpix, ypix = xy_pixels.T
# In matplotlib, 0,0 is the lower left corner, whereas it's usually the upper
# right for most image software, so we'll flip the y-coords
width, height = fig.canvas.get_width_height()
ypix = height - ypix
# this assumes that your data-points are equally spaced
s1 = xpix[1]-xpix[0]
points = ax.scatter(x,y,s=s1**2.,marker='s',edgecolors='none')
ax.axis([min(x)-1., max(x)+1., min(y)-1., max(y)+1.])
fig.savefig('test.png', dpi=fig.dpi)
第一种方法的缺点是符号重叠.我无法找到方法中的缺陷.我可以手动调整 s1
到
The downside of this first approach is, that the symbols overlap. I wasn't able to find the flaw in the approach. I could manually tweak s1
to
s1 = xpix[1]-xpix[0] - 13.
为了提供更好的结果,但我无法确定 13.
背后的逻辑.
to give better results, but I couldn't determine a logic behind the 13.
.
因此,第二种方法基于这个答案一个>.在这里,在绘图上绘制了各个正方形并相应地调整了大小.在某种程度上,它是一个手动散点图(使用循环来构建图形),因此根据数据集可能需要一段时间.
Hence, a second approach based on this answer. Here, individual squares are drawn on the plot and sized accordingly. In a way it's a manual scatter plot (a loop is used to construct the figure), so depending on the data-set it could take a while.
这种方法使用patches
而不是scatter
,所以一定要包含
This approach uses patches
instead of scatter
, so be sure to include
from matplotlib.patches import Rectangle
同样,使用相同的数据点:
Again, with the same data-points:
x = [1, 2, 3, 4, 2, 3, 3]
y = [0, 0, 0, 0, 1, 1, 2]
z = ['b', 'g', 'r', 'c', 'm', 'y', 'k'] # in your case, this is data
dx = [x[1]-x[0]]*len(x) # assuming equally spaced data-points
# you can use the colormap like this in your case:
# cmap = plt.cm.hot
fig = plt.figure()
ax = fig.add_subplot(111, aspect='equal')
ax.axis([min(x)-1., max(x)+1., min(y)-1., max(y)+1.])
for x, y, c, h in zip(x, y, z, dx):
ax.add_artist(Rectangle(xy=(x-h/2., y-h/2.),
color=c, # or, in your case: color=cmap(c)
width=h, height=h)) # Gives a square of area h*h
fig.savefig('test.png')
对 Rectangle
的注释:坐标是左下角,因此是 x-h/2.
这种方法给出了连接的矩形.如果我仔细观察这里的输出,它们似乎仍然重叠了一个像素-同样,我不确定这是否有帮助.
One comment on the Rectangle
: The coordinates are the lower left corner, hence x-h/2.
This approach gives connected rectangles. If I looked closely at the output here, they still seemed to overlap by one pixel - again, I'm not sure this can be helped.
这篇关于在 Matplotlib 中选择标记大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!