pceccon
pceccon

Reputation: 9844

Plot points over contour - Matplotlib / Python

I'm trying to plot some points over a contour using Matplotlib.

I have scalar field from which I want to plot the contour. However, my ndarray has a dimension 0 x 20, but my real space varies from -4 to 4.

I can plot this contour using this piece of code:

x, y = numpy.mgrid[-4:4:20*1j, -4:4:20*1j]

# Draw the scalar field level curves
cs = plt.contour(scalar_field, extent=[-4, 4, -4, 4])
plt.clabel(cs, inline=1, fontsize=10)

The problem is 'cause I have to plot some points over this plot, and this points are obtained using the ndarray, i.e., I get points varying as this array dimension.

I tried to plot these points using this code:

def plot_singularities(x_dim, y_dim, steps, scalar_field, min_points, max_points, file_path):
    """
    :param x_dim : the x dimension of the scalar field
    :param y_dim : the y dimension of the scalar field
    :param steps : the discretization of the scalar field
    :param file_path : the path to save the data
    :param scalar_field : the scalar_field to be plot
    :param min_points : a set (x, y) of min points of the scalar field
    :param max_points : a set (x, y) of max points of the scalar field
    """
    min_points_x = min_points[0]
    min_points_y = min_points[1]
    max_points_x = max_points[0]
    max_points_y = max_points[1]

    plt.figure()

    x, y = numpy.mgrid[-x_dim:x_dim:steps*1j, -y_dim:y_dim:steps*1j]

    # Draw the scalar field level curves
    cs = plt.contour(scalar_field, extent=[-x_dim, x_dim, -y_dim, y_dim])
    plt.clabel(cs, inline=1, fontsize=10)

    # Draw the min points
    plt.plot(min_points_x, min_points_y, 'ro')

    # Draw the max points
    plt.plot(max_points_x, max_points_y, 'bo')

    plt.savefig(file_path + '.png', dpi=100)
    plt.close()

But I got this image:

enter image description here

Which is not correct.

If I change this line:

cs = plt.contour(scalar_field, extent=[-x_dim, x_dim, -y_dim, y_dim])

For that one:

cs = plt.contour(scalar_field)

enter image description here

I get the desired behavior, but the extents doesn't show my real data space, but the ndarray dimension.

At last, if I don't plot these points (comment the plot() lines), I can the extents that I want:

enter image description here

But I have to plot the points. Both data are in the same space. But the contour() function allows me to specify the grid. I could found a manner to do this when plotting the points.

How can I properly set the extents?

Upvotes: 8

Views: 19363

Answers (2)

amd
amd

Reputation: 1727

If you don't provide x and y data corresponding to the scalar field, contour uses integer values up to the size of the array. That is why the axes are displaying the dimension of the array. The parameters extent should give the minimum and maximum x and y values; I assume this is what you mean by "data space." So the call to contour would be:

contour(scalar_field,extent=[-4,4,-4,4])

This can be reproduced by specifying x and y data:

contour(numpy.linspace(-4,4,20),numpy.linspace(-4,4,20),scalar_field)

Then the contour looks exactly as in your first plot. I assume the reason this is incorrect because the min and max points are not in the right places. Based on the info you gave, this is because min_points and max_points which you pass to your function are indices to the array scalar_field, so they correspond to integers, not the actual x and y values. Try to use these indices to access the x and y points by defining:

x=numpy.linspace(-4,4,20)
y=numpy.linspace(-4,4,20)

For example, if you have a min point of (0,1), it would correspond to (x[0], y[1]). I think a similar thing can be done with the mgrid, but I've never used that myself.

Upvotes: 5

Ajean
Ajean

Reputation: 5659

You want to plot both the contour and the points in the real data space, yes? plt.contour will take x and y values associated with the 2d array you have, and will plot on axes correctly.

xvals = -x_dim:x_dim:step  # I'm not sure about these ... but you get the idea
yvals = -y_dim:y_dim_step
plt.contour(xvals, yvals, scalar_field)

Upvotes: 0

Related Questions