0

Comments in code include proposed fix using np.linespace limits. This does not correct the problem in spite of the following given answer from the question "contourf() plots white space over finite data":If you want to make sure they all data is included you may define you own levels to use

plt.contourf(x, y, Z, np.linspace(Z.min(), Z.max(), 100)) The provided solution was thought to work then found not to in the older post. The statement was made the problem was not seen or not repeatable so the answer was never given. The code here reproduces the problem on both pi and win7 platforms and is repeatable. The areas with unwanted white space seem to associate with parallel contour lines which do not loop in the image. Note comments in the code where xc can be modified to change the shape of the data.

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

fig = plt.figure(figsize=(16,12))   #fill the screen
fig.canvas.set_window_title('<Test>')
ax = fig.gca()               # to work in 2d contour

x=[  274.0, 3174.6, 6075.2, 8975.8, 11876.4, 14777.0, 14777.0 , 11876.4, 8975.8,
  6075.2, 3174.6,  274.0, 274.0, 3174.6, 6075.2, 8975.8, 11876.4, 14777.0,
 14777.0, 11876.4, 8975.8, 6075.2, 3174.6, 274.0,   274.0,  3174.6, 6075.2,
  8975.8, 11876.4, 14777.0, 14777.0, 11876.4, 8975.8, 6075.2, 3174.6,  274.0 ]

y=[ 6737.2,  6737.2, 6737.2, 6737.2, 6737.2, 6737.2, 9907.4, 9907.4, 9907.4,
  9907.4, 9907.4, 9907.4, 13077.6, 13077.6,13077.6, 13077.6, 13077.6, 13077.6,
 16247.6, 16247.6, 16247.6, 16247.6, 16247.6, 16247.6, 19418.0, 19418.0, 19418.0,
 19418.0, 19418.0, 19418.0, 22588.2, 22588.2, 22588.2, 22588.2, 22588.2, 22588.2]

z=[154.11000061, 142.88999939, 137.19000244, 137.5, 143.42999268,
   155.47000122, 140.53999329, 126.16000366, 118.51999664, 118.43000031,
 125.22000122, 138.96000671, 131.03999329, 116.23999786, 108.23999786,
 108.90000153, 116.66999817, 132.6000061, 132.75999451, 117.56999969,
 111.65000153, 109.80000305, 117.29000092, 132.11000061, 141.44000244,
 127.08000183, 120.48000336, 120.58999634, 127.70999908, 141.05999756,
 156.22999573, 145.16000366, 139.33999634, 139.27999878, 145.63000488,
 157.00999451]

print(z)
xmax=(np.amax(x))
xmin=(np.amin(x))
ymax=(np.amax(y))
ymin=(np.amin(y))
zmax=(np.amax(z))
zmin=(np.amin(z))
xc=1 #change this from -40 to 1 to 40
yc=xc
Zheight=zmin
if xc==0:
    xc=.001
if yc==0:
    yc=.001
xcurv=int(1000000/xc)
ycurv=int(1000000/yc)  
z_surf = ((((x-(xmax+xmin)/2)/10)*((x-(xmax+xmin)/2)/10))/-xcurv + (((y-(ymax+ymin)/2)/10*(y-(ymax+ymin)/2)/10))/-ycurv ) +Zheight
zcorr=z-z_surf
zcorrmin=(np.amin(zcorr))
zcorrmax=(np.amax(zcorr))
X,Y= np.meshgrid(x,y)
Z = griddata((x, y), zcorr, (X, Y),method='nearest')
print("Zmin=",zmin,"Zmax=",zmax)
print("Zcorrmin=",zcorrmin,"Zcorrmax=",zcorrmax)

#im=ax.contourf(X, Y, Z, 15, alpha=.75, cmap = 'rainbow')   #white areas in contour map
im=ax.contourf(X, Y, Z,  np.linspace(Z.min(), Z.max(), 15), alpha=.75, cmap = 'rainbow') #supposed to fix white space but doesn't (3d surface and wireframe work fine with this data)
C = plt.contour(X, Y, Z, 15, colors='black')
plt.clabel(C, inline=1, fontsize=10)

v = np.linspace(zcorrmin, zcorrmax, 15, endpoint=True)
fig.colorbar(im,ax=ax,ticks=v)

plt.xticks(())
plt.yticks(())
plt.show()

1 Answers1

0

The problem is that the grid is too coarse. There will be parts in the figure where no contouring can happen.

The solution is to interpolate the data on a finer grid.

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

fig = plt.figure(figsize=(16,12))   #fill the screen
fig.canvas.set_window_title('<Test>')
ax = fig.gca()               # to work in 2d contour

x=[  274.0, 3174.6, 6075.2, 8975.8, 11876.4, 14777.0, 14777.0 , 11876.4, 8975.8,
  6075.2, 3174.6,  274.0, 274.0, 3174.6, 6075.2, 8975.8, 11876.4, 14777.0,
 14777.0, 11876.4, 8975.8, 6075.2, 3174.6, 274.0,   274.0,  3174.6, 6075.2,
  8975.8, 11876.4, 14777.0, 14777.0, 11876.4, 8975.8, 6075.2, 3174.6,  274.0 ]

y=[ 6737.2,  6737.2, 6737.2, 6737.2, 6737.2, 6737.2, 9907.4, 9907.4, 9907.4,
  9907.4, 9907.4, 9907.4, 13077.6, 13077.6,13077.6, 13077.6, 13077.6, 13077.6,
 16247.6, 16247.6, 16247.6, 16247.6, 16247.6, 16247.6, 19418.0, 19418.0, 19418.0,
 19418.0, 19418.0, 19418.0, 22588.2, 22588.2, 22588.2, 22588.2, 22588.2, 22588.2]

z=[154.11000061, 142.88999939, 137.19000244, 137.5, 143.42999268,
   155.47000122, 140.53999329, 126.16000366, 118.51999664, 118.43000031,
 125.22000122, 138.96000671, 131.03999329, 116.23999786, 108.23999786,
 108.90000153, 116.66999817, 132.6000061, 132.75999451, 117.56999969,
 111.65000153, 109.80000305, 117.29000092, 132.11000061, 141.44000244,
 127.08000183, 120.48000336, 120.58999634, 127.70999908, 141.05999756,
 156.22999573, 145.16000366, 139.33999634, 139.27999878, 145.63000488,
 157.00999451]


xmax=(np.amax(x))
xmin=(np.amin(x))
ymax=(np.amax(y))
ymin=(np.amin(y))
zmax=(np.amax(z))
zmin=(np.amin(z))

z_surf = ((((x-(xmax+xmin)/2)/10)*((x-(xmax+xmin)/2)/10))/-1e6 + \
          (((y-(ymax+ymin)/2)/10*(y-(ymax+ymin)/2)/10))/-1e6 ) + zmin
zcorr=z-z_surf

X,Y= np.meshgrid(np.linspace(xmin, xmax, 51),np.linspace(ymin, ymax, 51))
Z = griddata((x, y), zcorr, (X, Y),method='linear')

im=ax.contourf(X, Y, Z,  15, alpha=.75, cmap = 'rainbow')
C = ax.contour(X, Y, Z, 15, colors='black')

ax.clabel(C, inline=1, fontsize=10)

fig.colorbar(im,ax=ax)

ax.scatter(x,y,c="k", label="original grid")
ax.scatter(X,Y,c="crimson", s=4, label="fine grid")
ax.legend(framealpha=1)
plt.xticks(())
plt.yticks(())
plt.show()

Here I marked the original grid with black dots, and the refined grid with red dots. The interpolation is still linear. But for smoother curves you may use method='cubic'.

enter image description here

ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712
  • Thank you! I had even tried going from this 36 datapoint file to a 900 datapoint file without success. I had assumed meshgrid generated its grid based on the array size so I was surprised when the 900 point version also failed. I have tried both my datasets with your fix and they work. THANK YOU! – Jim Colvin Nov 14 '18 at 22:44
  • Hi, I am facing a similar issue. I am trying to get a contour plot for a dataset and I have created a data frame for this purpose. The X and Y values are the index values and the column names(converted to a separate numeric list) respectively. While plotting I am getting some regions of blank space corresponding to values with lower magnitude (the df has logarithmic values but no negatives or NaN). Can a coarse grid be a reason for this? It is not a function so can't make a finer mesh as suggested in this answer. – Achintya Patra Oct 24 '21 at 17:46