Ivan
Ivan

Reputation: 20101

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?

Upvotes: 8

Views: 6108

Answers (2)

Saullo G. P. Castro
Saullo G. P. Castro

Reputation: 59015

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.

Upvotes: 8

bogatron
bogatron

Reputation: 19159

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)

Upvotes: 3

Related Questions