python scatter plot area size proportional axis length

前端 未结 1 1052
眼角桃花
眼角桃花 2021-01-16 03:03

I\'m getting quite desperate about this, I couldn\'t find anything on the www so far.

Here\'s the situation:

  • I am working with Python.
  • I have
1条回答
  •  有刺的猬
    2021-01-16 04:02

    I'm jumping in from your other stackoverflow question. I think the approach you presented as an answer to the present question won't work exactly as you want for the following reasons:

    • First, the size of the markers is in points, not in pixels. In typography, the point is the smallest unit of measure and correspond in matplotlib to a fixed length of 1/72 inch. In contrast, the size of a pixel will vary following the figure dpi and size.
    • Second, the size of the markers in plt.scatter are related to the diameter of the circles, not the radius.

    So the size in points of each marker should be calculated as:

    size_in_points = (2 * radius_in_pixels / fig_dpi * 72 points/inch)**2

    Moreover, as shown in the MWE below, it is possible to calculate the size of the marker radius in pixels directly with matplotlib transformations, without having to generate an empty figure beforehand:

    import numpy as np
    import matplotlib.pyplot as plt
    
    plt.close('all')
    
    # Generate some data :
    N = 25
    x = np.random.rand(N) + 0.5
    y = np.random.rand(N) + 0.5
    r = np.random.rand(N)/10
    
    # Plot the data :
    fig = plt.figure(facecolor='white', figsize=(7, 7))
    ax = fig.add_subplot(111, aspect='equal')
    ax.grid(True)
    scat = ax.scatter(x, y, s=0, alpha=0.5, clip_on=False)
    ax.axis([0, 2, 0, 2])
    
    # Draw figure :
    fig.canvas.draw()
    
    # Calculate radius in pixels :
    rr_pix = (ax.transData.transform(np.vstack([r, r]).T) -
              ax.transData.transform(np.vstack([np.zeros(N), np.zeros(N)]).T))
    rpix, _ = rr_pix.T
    
    # Calculate and update size in points:
    size_pt = (2*rpix/fig.dpi*72)**2
    scat.set_sizes(size_pt)
    
    # Save and show figure:
    fig.savefig('scatter_size_axes.png')
    plt.show()
    

    A point at (1, 1) with radius 0.5 assigned will result in a circle in the plot centered at (1, 1) and with the border going throught the points (1.5, 1), (1, 1.5), (0.5, 1) and (1, 0.5):

    0 讨论(0)
提交回复
热议问题