2015-10-22 5 views
2

Я хотел бы нарисовать поверхностный участок matplotlib с 4 размерами. Первоначально, я бы данные в:Изменение лицевых цветов в четырехмерной поверхности матплотблиба

[(X, Y, Z, P)] 

Так что я хотел бы иметь 3D Surface, но с палитрой, которая представлена ​​значениями P.

Я видел неплохое решение для своей проблемы here.

Так что я расщепляется мои данные в двух наборах данных:

1. [(X, Y, Z)] (called data in my code) and 
2. [(X, Y, P)] (called shade in my code) 

и попытался осуществить то, что Оливер У. предложил в конце своего ответа. К сожалению, я получаю следующее сообщение об ошибке:

Exception in Tkinter callback 
Traceback (most recent call last): 
    File "c:\Python27\lib\lib-tk\Tkinter.py", line 1532, in __call__ 
    return self.func(*args) 
    File "c:\Python27\lib\lib-tk\Tkinter.py", line 583, in callit 
    func(*args) 
    File "C:\Users\Raphael\Documents\NetBeansProjects\GammaVolaFund\src\GUI.py", line 413, in repeat 
    self.a2.plot_surface(grid_x, grid_y, grid_z, facecolors=fc, rstride=1, cstride=1, linewidth=0, antialiased=False, shade=False) 
    File "c:\Python27\lib\site-packages\mpl_toolkits\mplot3d\axes3d.py", line 1625, in plot_surface 
    colset.append(fcolors[rs][cs]) 
IndexError: index 4 is out of bounds for axis 0 with size 4 

Вот мой код:

if "surface" in val: 
       self.a2.cla() #<-- this is the existing axis 
       data = val['surface']['surface'] 
       shade = np.array(val['surface']['shade']) 

       x, y, z = zip(*shade) 
       z = map(float, z) 
       grid_x, grid_y = np.mgrid[min(x):max(x):100j, min(y):max(y):100j] 
       grid_z = griddata((x, y), z, (grid_x, grid_y), method='cubic') 
       grid_z = np.nan_to_num(grid_z) 
       grid_z /= grid_z.max() 

       surf = self.a2.plot_surface(grid_x, grid_y, grid_z, rstride=1, cstride=1, cmap='jet', linewidth=0, antialiased=False, shade=False) 
       self.canvas2.draw() #<- this has to be here to be able to use .get_facecolors() 
       fc = surf.get_facecolors() 

       self.a2.cla() 

       x, y, z = zip(*data) 
       z = map(float, z) 
       grid_x, grid_y = np.mgrid[min(x):max(x):100j, min(y):max(y):100j] 
       grid_z = griddata((x, y), z, (grid_x, grid_y), method='cubic') 
       grid_z = np.nan_to_num(grid_z) 

       self.a2.plot_surface(grid_x, grid_y, grid_z, facecolors=fc, rstride=1, cstride=1, linewidth=0, antialiased=False, shade=False) 

       self.canvas2.draw() 

Я получаю значение из очереди, поэтому это может быть немного uncoventional. После получения данных из очереди я хотел бы обновить свой сюжет, как описано выше. К сожалению, мои данные имеют ту же длину, что и ширина, иначе я мог бы использовать первую часть Оливерса.

Есть ли у кого-нибудь идеи, как это можно устранить?


Update: вот наборы данных:

Вот два набора данных:

data: 
[(7.0, 2025.0, 0.14473006433340618), (7.0, 2030.0, 0.14062607337060892), (7.0, 2020.0, 0.1472362005164195), (7.0, 2040.0, 0.1319299850069502), (7.0, 2050.0, 0.12497732155598347), (38.0, 2040.0, 0.13013012553239645), (38.0, 2050.0, 0.12603323962393054), (38.0, 2020.0, 0.13923258922827567), (38.0, 2025.0, 0.1371105447700807), (38.0, 2030.0, 0.13509217383084055), (7.0, 2035.0, 0.13590798149865668), (7.0, 2055.0, 0.12122832793319385), (38.0, 2045.0, 0.1283033928063951), (38.0, 2055.0, 0.12376727418426803), (7.0, 2045.0, 0.12747859242231532), (38.0, 2035.0, 0.13268757208364956), (28.0, 2040.0, 0.1336849736130551), (28.0, 2045.0, 0.1304881237751081), (28.0, 2050.0, 0.12838196945626767), (28.0, 2055.0, 0.12594690413524617), (28.0, 2020.0, 0.1426266123329183), (28.0, 2025.0, 0.14105151195673143), (28.0, 2030.0, 0.1373925658286551), (28.0, 2035.0, 0.13591663964396278), (0.0, 2040.0, 0.13520161504277875), (0.0, 2045.0, 0.12954944890882458), (0.0, 2050.0, 0.12265378802459166), (0.0, 2055.0, 0.11829387116926045), (0.0, 2020.0, 0.15941121559558222), (0.0, 2025.0, 0.15264786078400508), (0.0, 2030.0, 0.14752256519025417), (0.0, 2035.0, 0.1410671600261568), (14.0, 2055.0, 0.12290037442735217), (14.0, 2050.0, 0.12609729724766153), (14.0, 2045.0, 0.12957885633601618), (14.0, 2040.0, 0.13191236031636167), (14.0, 2035.0, 0.13486885042437866), (14.0, 2030.0, 0.13735387420193756), (14.0, 2025.0, 0.14117139286403094), (14.0, 2020.0, 0.14410654811736545), (21.0, 2040.0, 0), (21.0, 2045.0, 0.1280055085205311), (21.0, 2050.0, 0.1253472936767727), (21.0, 2055.0, 0.12311151990554384), (21.0, 2020.0, 0.14150097628342895), (21.0, 2025.0, 0.13862160845657018), (21.0, 2030.0, 0.1357506086172204), (21.0, 2035.0, 0.1334635475535782), (35.0, 2040.0, 0), (35.0, 2045.0, 0.12909917255032188), (35.0, 2050.0, 0.12671861528494266), (35.0, 2055.0, 0.12432370882456634), (35.0, 2020.0, 0.14029296457584772), (35.0, 2025.0, 0.13813227231612185), (35.0, 2030.0, 0.13606666884642726), (35.0, 2035.0, 0)] 
shape: 
[(7.0, 2025.0, 1162), (7.0, 2030.0, 381), (7.0, 2020.0, 944), (7.0, 2040.0, 3074), (7.0, 2050.0, 2141), (38.0, 2040.0, 514), (38.0, 2050.0, 393), (38.0, 2020.0, 15), (38.0, 2025.0, 7), (38.0, 2030.0, 30), (7.0, 2035.0, 63), (7.0, 2055.0, 1676), (38.0, 2045.0, 123), (38.0, 2055.0, 2), (7.0, 2045.0, 3924), (38.0, 2035.0, 23), (28.0, 2040.0, 7238), (28.0, 2045.0, 3908), (28.0, 2050.0, 16383), (28.0, 2055.0, 2835), (28.0, 2020.0, 2058), (28.0, 2025.0, 1481), (28.0, 2030.0, 831), (28.0, 2035.0, 1386), (0.0, 2040.0, 9437), (0.0, 2045.0, 0), (0.0, 2050.0, 0), (0.0, 2055.0, 0), (0.0, 2020.0, 0), (0.0, 2025.0, 901), (0.0, 2030.0, 0), (0.0, 2035.0, 0), (14.0, 2055.0, 384), (14.0, 2050.0, 1482), (14.0, 2045.0, 928), (14.0, 2040.0, 800), (14.0, 2035.0, 0), (14.0, 2030.0, 21), (14.0, 2025.0, 124), (14.0, 2020.0, 400), (21.0, 2040.0, 598), (21.0, 2045.0, 385), (21.0, 2050.0, 397), (21.0, 2055.0, 817), (21.0, 2020.0, 40), (21.0, 2025.0, 13), (21.0, 2030.0, 26), (21.0, 2035.0, 24), (35.0, 2040.0, 141), (35.0, 2045.0, 365), (35.0, 2050.0, 324), (35.0, 2055.0, 49), (35.0, 2020.0, 294), (35.0, 2025.0, 422), (35.0, 2030.0, 112), (35.0, 2035.0, 22)] 
+0

вы должны ответить на свой вопрос, и принять ваш ответ. Вы также можете показать фигуру, чтобы легче понять, что вы делаете. – jrjc

+0

Спасибо. Я довольно новичок в stackoverflow, извините за это. Я приложил ответ ниже. –

ответ

1

Решение: Я нашел решение проблемы:

self.a2.cla() 
data = np.array(val['surface']['surface']) 
x, y, z, colors = data[:,0], data[:,1], data[:,2], data[:,3], 
grid_x, grid_y = np.mgrid[min(x):max(x):50j, min(y):max(y):50j] 
z = griddata((x, y), z, (grid_x, grid_y), method='cubic') 
colors = griddata((x, y), colors, (grid_x, grid_y), method='cubic') 
y, x = grid_y.ravel(), grid_x.ravel() 

y_coords, x_coords = np.unique(y), np.unique(x) 
y_centers, x_centers = [ arr[:-1] + np.diff(arr)/2 for arr in (y_coords, x_coords)] 

# Convert back to a 2D grid, required for plot_surface: 
Y = y.reshape(y_coords.size, -1) 
X = x.reshape(-1, x_coords.size) 
Z = z.reshape(X.shape) 
C = colors.reshape(X.shape) 

#Normalize the colors to fit in the range 0-1, ready for using in the colormap: 
Z -= Z.min() 
Z /= Z.max() 

C -= C.min() 
C /= C.max() 

interp_func = RectBivariateSpline(x_coords, y_coords, C.T, kx=1, ky=1) # the kx, ky define the order of interpolation. Keep it simple, use linear interpolation. 

self.a2.plot_surface(X,Y,Z, facecolors=cm.hot(interp_func(x_centers, y_centers).T), rstride=1, cstride=1, linewidth=1, antialiased=False, shade=False) # only added because of this very limited dataset 

self.canvas2.draw() 

Это не решает проблему с get_facecolors, но если она работает так кругом. Это нормально для меня.

Вот как это выглядит: 3D Plot with 4D Surface

 Смежные вопросы

  • Нет связанных вопросов^_^