首页 文章

在Matplotlib中选择标记大小

提问于
浏览
9

我在matplotlib中使用方形标记进行散点图,如下所示:

small_marker
.

我希望实现这样的目标:

enter image description here

这意味着我必须调整标记大小和图形大小/比例,使标记之间没有空白区域 . 每个索引单位也应该有一个标记(x和y都是整数),所以如果y从60变为100,则y方向应该有40个标记 . 目前我正在手动调整它 . 对于实现这一目标的最佳方法有什么想法吗?

1 回答

  • 7

    我发现了两种方法:

    第一个是基于this answer . 基本上,您可以确定相邻数据点之间的像素数,并使用它来设置标记大小 . scatter 中的标记大小以区域的形式给出 .

    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

    s1 = xpix[1]-xpix[0] - 13.
    

    为了给出更好的结果,但我无法确定 13. 背后的逻辑 .

    因此,第二种方法基于this answer . 在这里,在图上绘制单个正方形并相应地调整大小 . 在某种程度上,它是一个手动散点图(循环用于构造图形),因此根据数据集可能需要一段时间 .

    此方法使用 patches 而不是 scatter ,因此请务必包含

    from matplotlib.patches import Rectangle
    

    同样,使用相同的数据点:

    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.
    这种方法给出了连接的矩形 . 如果我仔细观察这里的输出,他们似乎仍然重叠一个像素 - 再次,我不确定这可以帮助 .

相关问题