Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

matplotlib contour input array order

Question: what order does the contour from matplotlib expect for the input 2D array?

Elaborate: Matplotlib contour documentation says that the routine call is

x_axis = np.linspace(10,100,n_x)
y_axis = np.linspace(10,100,n_y)
matplotlib.pyplot.contour(x_axis, y_axis, scalar_field)

Where scalar_field must be a 2D array. For example, the scalar_field can be generated by

scalar_field = np.array( [(x*y) for x in x_axis for y in y_axis])
scalar_field = scalar_field.reshape(n_x, n_y)

If scalar_field is given to contour,

plt.contour(x_axis, y_axis,scalar_field) #incorrect

the orientation of the plot is incorrect (rotated). To restore the proper orientation the scalar_field must be transposed:

plt.contour(x_axis, y_axis,scalar_field.transpose()) #correct

So what is the order that contour expect that scalar_field has?

like image 516
Ivan Avatar asked Sep 16 '13 18:09

Ivan


People also ask

What is Z in Contourf?

contourf( Z ) creates a filled contour plot containing the isolines of matrix Z , where Z contains height values on the x-y plane. MATLAB® automatically selects the contour lines to display. The column and row indices of Z are the x and y coordinates in the plane, respectively.

What does Contourf do in Python?

The contourf() function in pyplot module of matplotlib library is used to plot contours. But contourf draw filled contours, while contourf draws contour lines. Parameters: This method accept the following parameters that are described below: X, Y: These parameter are the coordinates of the values in Z.

How do you plot 3d contour in Python?

ax = plt.axes(projection='3d') # Data for a three-dimensional line zline = np.linspace(0, 15, 1000) xline = np.sin(zline) yline = np.cos(zline) ax.plot3D(xline, yline, zline, 'gray') # Data for three-dimensional scattered points zdata = 15 * np.random.random(100) xdata = np.sin(zdata) + 0.1 * np.random.randn(100) ydata ...


2 Answers

You should plot using contour passing also 2-D arrays for X and Y, then each point in your scalar_field array will correspond to a coordinate (x, y) in X and Y. You can conveniently create X and Y using numpy.meshgrid:

import matplotlib.pyplot as plt
import numpy as np

X, Y = np.meshgrid(x_axis, y_axis, copy=False, indexing='xy')
plt.contour(X, Y, scalar_field)    

The argument indexing can be changed to 'ij' if you want the x coordinate to represent line and y to represent column, but in this case scalar_fied must be calculated using ij indexing.

like image 105
Saullo G. P. Castro Avatar answered Sep 20 '22 10:09

Saullo G. P. Castro


The x values are expected to correspond to the columns of data, not the rows (i.e., x is the horizontal axis and y is the vertical axis). You have it reversed, which is why you are having to transpose the z values to make it work.

To avoid requiring the transpose, create your array as:

scalar_field = np.array( [(x*y) for y in y_axis for x in x_axis])
scalar_field = scalar_field.reshape(n_y, n_x)
like image 38
bogatron Avatar answered Sep 19 '22 10:09

bogatron