3

I am trying to plot some 2D values in a Basemap with contourf (matplotlib).

However, contourf by default interpolates intermediate values and gives a smoother image of the data.

Is there any way to make contourf to stop interpolating between values?

I have tried by adding the keyword argument interpolation='nearest' but contourf does not use it. Other option would be to use imshow, but there are some functionalities of contourf that do not work with imshow.

I am using python 3.6.3 and matplotlib 2.1.2

Numlet
  • 819
  • 1
  • 9
  • 21
  • 5
    The complete concept of a contour plot is to interpolate. If you don't want that, you cannot use a contour plot. I guess you should rather tell what plot you're aiming at and what hinders you to obtain it. – ImportanceOfBeingErnest Mar 07 '18 at 12:36

3 Answers3

5

try 'pcolormesh' instead, you can use it to plot 2D values without interpolation between them.

'pcolormesh'(from matplotlib documentation):

Create a pseudocolor plot with a non-regular rectangular grid.

code example:

import matplotlib.pyplot as plt
plt.pcolormesh(data)
plt.show()

here you can see how to use 'pcolormesh' in a similar way to 'contourf' (there is also an example figure):

https://matplotlib.org/examples/images_contours_and_fields/pcolormesh_levels.html

Avimsh
  • 131
  • 1
  • 4
2

I had the same issue when plotting class decision boundaries (colors) with uncertainty (blending color to white). Between two boundaries I had colors of other classes due to interpolation. These boundaries are wrong. Look at the transition from blue to red:

Wrong decision boundaries

I solved this by plotting only one class at a time. This can be done with masked arrays:

# C contains classes 0, 1, 2 as mesh
# CU contains classes with uncertainty, CU = 2 * C + U, where 0 <= U <= 1
# xx and yy are the mesh variables
for cl in np.unique(C):   # iterate over red, green, blue classes
    mask = C != cl
    xx_ma = np.ma.MaskedArray(xx, mask)
    yy_ma = np.ma.MaskedArray(yy, mask)
    CU_ma = np.ma.MaskedArray(CU, mask)
    cnt = plt.contourf(xx_ma, yy_ma, CU_ma, vmin=0, vmax=5,
                       cmap=cmap, levels=len(np.unique(CU)))

This is the result:

enter image description here


When using pcolormesh, you don't need to plot the classes separately, but the data must be in a different format. Basically you need an xy-mesh for the corners (grid) and another xy-mesh for the centers (values):

(X[i+1, j], Y[i+1, j])          (X[i+1, j+1], Y[i+1, j+1])
                      +--------+
                      | C[i,j] |
                      +--------+
    (X[i, j], Y[i, j])          (X[i, j+1], Y[i, j+1]),

The result looks like this (with precise corners now):

enter image description here

John
  • 1,472
  • 1
  • 19
  • 22
-3

Given that the question has not been updated to clearify the actual problem, I will simply answer the question as it is:

No, there is no way that contour would not interpolate because the whole concept of a contour plot is to interpolate the values.

ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712