3

Pardon my ignorance but somehow all interpolation, smoothing of 2D maps solutions require a relationship Z~f(x,y) and does not fit my problem. This is closest to my problem : smoothing surface plot from matrix

I have three columns of same lengths: X coordinates, Y coordinates, and the Z-value

I can plot a scatterplot like this

scatterplot

with Z as the filler / colormap, but it looks like points on a grid with regular intervals.

I want to interpolate and smooth them to fill in the gaps between the gridpoints but I don't know what the Z~f(x,y) is. Is there a way to achieve this?

UPDATE credit to @Wombatz for the interpolation (see solution below). I have added his contribution to my code and figured out how to resample 1D-array Z-col to a 2D-array that fits my (x,y) array. My code below:

import matplotlib.pyplot as plt
from matplotlib.pyplot import imshow
from scipy.interpolate import griddata
import numpy as np

x = [0,0,1,1,2,2] #1D
y = [0,1,0,1,0,1] #1D
Z = [1,2,3,4,5,6] #1D

extent = (min(x), max(x), min(y), max(y))
xs,ys = np.mgrid[extent[0]:extent[1]:3j, extent[2]:extent[3]:2j] #2D x,y
Z_resampled = griddata((x, y), Z, (xs, ys)) #2D z


imshow(z_resampled, interpolation="gaussian", extent=extent, origin="lower")

Scatterplot of x,y,z: scatter

My code gives me this: smoothed

Hud
  • 301
  • 1
  • 12

1 Answers1

2

I assume you have the following data:

  • x: the x values [-120, -100, ..., 140, 160]
  • y: the y values [-180, -160, ..., 80, 100]
  • z: a 2d array containing the z values for each point in the grid

Now you can plot the data as an image which does the interpolation for you:

from matplotlib.pyplot import imshow

extent = [x.min(), x.max(), y.min(), y.max()]
imshow(z, interpolation="none", extent=extent, origin="lower")

scatter plot as image

The extent defines the axes for the image. You can play around with the interpolation parameter.

The black circles are the markers from the scatter plot (not shown in the code).

If you need the scatter plot markers to be in the center of each pixel, you must change the extent like this:

ox = (x.max() - x.min()) / (x.size * 2)
oy = (y.max() - y.min()) / (y.size * 2)
extent = [x.min() - ox, x.max() + ox, y.min() - oy, y.max() + oy]

Together with bilinear interpolation this looks as follows:

enter image description here

Wombatz
  • 4,958
  • 1
  • 26
  • 35
  • Cheers for the quick response! How did you prepare the 2d-array from a single z-column? – Hud Dec 18 '19 at 01:19
  • @Hud im not sure what you mean by a single z-column, since your example looks 2 dimensional. Maybe you could edit your question to include a minimal example how **you** prepared the data. Then i can adapt my answer. – Wombatz Dec 18 '19 at 01:31
  • Added the solution. Cheers Wombatz – Hud Dec 18 '19 at 19:23