1

I'm trying to plot a 3D surface plot, using a fourth variable as a color scale. The distribution of the three input variables is not regularly spaced, but I think I already solved that part using the griddata method. Each one of the variables is a list with 20 values inside, one of the variables is the output of a numerical code using the other 3 variables. The idea is to use 2 of the input variables plus the output of the numerical code for the surface plot, and using the third input variable for the color scale. When I'm trying to use the value of the other variable for the color scale using the facecolor argument I haven´t be able to produce the right plot. I already tried to normalize the values of this variable to interval 0-1, and several other ways but in the majority of cases I just get a plot with a uniform color or some Type error. Below you can find the code that I'm trying to run.

from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
import matplotlib.pyplot as plt
import numpy as np
from scipy.interpolate import griddata
import matplotlib

#opening the files with the 4 variables
p1=open('par1log10.txt','r')
p2=open('par2log10.txt','r')
p3=open('par3log10.txt','r')
output=open('response.txt','r')

par1, par2, par3, output1 = ([] for i in range(4))

for a in p1:
    par1.append(float(a))

for b in p2:
    par2.append(float(b))

for c in p3:
    par3.append(float(c))

for d in output:
    output1.append(float(d))


p1.close()
p2.close()
p3.close()
output.close()

data1=np.array(par1)
data2=np.array(par2)
data3=np.array(par3)
output=np.array(output1)

fig = plt.figure()

xi = np.linspace(data1.min(),data1.max(),200)
yi = np.linspace(data2.min(),data2.max(),200)
wi = np.linspace(data3.min(),data3.max(),200)

# Interpoling unstructured data 
zi = griddata((data1, data2), output, (xi[None,:], yi[:,None]), method='cubic')
# removing NaNs from the array
zi = np.nan_to_num(zi)

ax = fig.add_subplot(1, 1, 1, projection='3d', azim=210)

xig, yig = np.meshgrid(xi, yi)

#normalizing variable to interval 0-1
data3col=data3/data3.max()

surf = ax.plot_surface(xig, yig, zi, rstride=1, cstride=1, facecolor=cm.jet(data3col), linewidth=0, antialiased=False, shade=False)

ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
ax.set_zlabel('Z Label')
#fig.colorbar(surf, shrink=0.5, aspect=5)
ax.set_zlim(0, 350000)

plt.show()

This version of the code just shows a blue surface, I also have tried, unsuccessfully, to build my own colormap based on the values of a list and then used that colormap, but without results. This is my first question here, so I hope I didn't violate any rules or made any mistakes. Any help will be greatly valued.

  • Welcome, Ariel. Have a look at this question and its answers: [set colorbar range in matplotlib](http://stackoverflow.com/questions/3373256/set-colorbar-range-in-matplotlib). I think what you are after is either `plt.clim(min(zi),max(zi))` or `norm=mpl.colors.Normalize(vmin=-min(zi), vmax=max(zi))`. If these suggestions do not help you, please comment accordingly. – Schorsch Jul 25 '14 at 11:48
  • 1
    @Schorsch. Hi, Thanks for your help. The example that you mentioned used as a third variable, and also for the colormap, a third variable which is derived from a function of the input parameters x,y after using method meshgrid (which change dimensionality of original data). What I'm trying to use as a source for the colormap is a 4th variable, of a different shape from the ones used for the 3d visualization. – Ariel_Vidal Jul 28 '14 at 05:27
  • @Schorsch The main point is that sizes of original data changes after using meshgrid method and the fourth variable, what I want for colorscale, doesn`t pass through meshgrid method, so I don´t know how to use this data list in their original shape. Your suggestion works great for 3d data, but if I'm right doesn`t work if I'm trying to include a 4th variable. – Ariel_Vidal Jul 28 '14 at 05:27
  • Have you tried repeating the grid interpolation with the fourth instead of the third variable? That what you end up with both the third and the fourth variable at the same locations as the x/y-coordinates. Then, you can easily use the fourth as color on a 3D surface. – Schorsch Jul 28 '14 at 12:44
  • @Schorsch Yes,I tried interpolating the fourth variable with 'griddata' it works fine, it produces an array with the required shape but the array obtained contains NaN values, which after converting to num generates an array that doesn't fit the requirements as a colormap, I guess is because it have too many zeros on it. – Ariel_Vidal Jul 31 '14 at 22:10

0 Answers0