If you do not have a regular grid, using triangular surface interpolation may be a good choice.
In this example and the above one, if you have longer data, you only have to check the boundary of the plot.
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.tri as tri
sns.set(style="white")
x = np.array([1,4,6,7,8,2,6])
y = np.array([7,7,8,9,0,1,2])
z = np.array([8,9,7,1,2,2,3])
fig = plt.figure(figsize=(10, 10))
ax = fig.add_subplot(111)
nptsx, nptsy = 100, 100
xg, yg = np.meshgrid(np.linspace(x.min(), x.max(), nptsx),
np.linspace(y.min(), y.max(), nptsy))
triangles = tri.Triangulation(x, y)
tri_interp = tri.CubicTriInterpolator(triangles, z)
zg = tri_interp(xg, yg)
# change levels here according to your data
levels = np.linspace(0, 10, 5)
colormap = ax.contourf(xg, yg, zg, levels,
cmap=plt.cm.Blues,
norm=plt.Normalize(vmax=z.max(), vmin=z.min()))
# plot data points
ax.plot(x, y, color="#444444", marker="o", linestyle="", markersize=10)
# add a colorbar
fig.colorbar(colormap,
orientation='vertical', # horizontal colour bar
shrink=0.85)
# graph extras: look at xlim and ylim
ax.set_xlim((0, 10))
ax.set_ylim((0, 10))
ax.set_aspect("equal", "box")
plt.show()
This is the output :
