Home > Mobile >  set_position and set_size_inches does not work properly when overlaying imshow and scatter in matplo
set_position and set_size_inches does not work properly when overlaying imshow and scatter in matplo

Time:01-20

I am trying to create an image from a matrix z2 over a raster defined by np.meshgrid(grid_x, grid_y) such that the value of the image at vx=grid_x[i], vy=grid_y[j] is z2[i, j]. On top of this image, I am trying to add a scatter plot of a number of points obtained by three vectors x, y, z such that the i-th point has the coordinate (x[k], y[k]) and the value z[k]. All of these scattered points lies within the region of the aforementioned raster.

Here's an example of the aforementioned data I am trying to plot.

import numpy as np

np.random.seed(1)
z2 = np.ones((1000, 1000)) * 0.66
z2[0, 0] = 0
z2[-1, -1] = 1
x = np.random.rand(1000) * 1000
y = np.random.rand(1000) * 1000
z = np.random.rand(1000)
grid_x = np.linspace(0, 999, 1000)
grid_y = np.linspace(0, 999, 1000)

In order to do this, I am using a 2D plot where the x and y values are used to define the position of the points and z is indicated by a color drawn from a colormap.

What is required of this image is that 1) there should be no white space between the actual plot and the edge of the figure; 2) the unit length on the x and y axis should be equal; 3) the image should not be too large. In order to achieve these, I am using the following code for plotting.

import matplotlib.pyplot as plt
from matplotlib import cm

def plot_img(x, y, z, grid_x, grid_y, z2, set_fig_size=True):

    # determine the figure size
    if set_fig_size:
        height, width = np.array(z2.shape, dtype=float)
        dpi = max(max(640 // height, 640 // width), 1)
        width, height = width * dpi, height * dpi
        plt.gcf().set_size_inches(width, height)
        plt.gcf().set_dpi(dpi)

    # plot the figure
    plt.gca().axis('off')
    plt.gca().axis('equal')
    plt.gca().set_position([0, 0, 1, 1])
    plt.xlim((grid_x[0], grid_x[-1]))
    plt.ylim((grid_y[0], grid_y[-1]))

    # the raster
    cmap = cm.get_cmap('gray')
    cmap.set_bad(color='red', alpha=0.5)
    plt.imshow(z2, cmap=cmap, interpolation='none', origin='lower',
                   extent=(grid_x[0], grid_x[-1], grid_y[0], grid_y[-1]))

    # the scatter plot
    min_z, max_z = np.min(z), np.max(z)
    c = (z - min_z) / (max_z - min_z)
    plt.scatter(x, y, marker='o', c=c, cmap='Greens')

    plt.show()

Strangely, when I run plot_img(x, y, z, grid_x, grid_y, z2) using the aforementioned example data, the following image shows up.

enter image description here

Essentially, only the raster data got plotted, while the scattered data is not.

I then tried plot_img(x, y, z, grid_x, grid_y, z2, set_fig_size=False). The result is

enter image description here

Note that here to clearly show the white spaces in the figure, I kept the background of PyCharm surrounding it. Essentially, there are white spaces that I do not wish included in this figure.

I wonder why this is happening, and how I can fix the code to get the correct output, which is essentially the second result without the white spaces. Thanks!

CodePudding user response:

Replace your dpi and figsize code by

# determine the figure size
height, width = np.array(z2.shape, dtype=float)
dpi = 200
# get size in inches:
width, height = height / dpi, width / dpi
plt.gcf().set_size_inches(width, height)
plt.gcf().set_dpi(dpi)

and you will have a 1000x1000 pixel figure, which at 200 dpi is 5"x5".

  •  Tags:  
  • Related