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
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")
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 gridNow 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")
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: