2016-02-23 1 views
2

Возможно ли построить несколько поверхностей на одном рисунке кузнеца? Вот моя попытка. Команда ax.plot_surface, похоже, перезагружает фигуру, так как я получаю только одну плоскость в полученном графике. Я надеюсь создать «штабелированные» самолеты, каждый из которых имеет отличительные цвета, и цветную полосу, показывающую числовое значение каждого цвета. В настоящее время мои цвета проявляются неправильно.matplotlib правильные цвета/цветная панель для участка с несколькими поверхностями каждый из другого цвета

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

dat = open('ex.csv', 'w') 
dat.write('x,y,z,c\n') 
for x in range(20): 
    for y in range(20): 
     for c in range(0,7): 
      dat.write(','.join([str(s) for s in [x,y,x+y+c,c/10.0,'\n']])) 
dat.close() 

fig = matplotlib.pyplot.gcf() 
dat = np.genfromtxt('ex.csv', delimiter=',',skip_header=1) 
X_dat = dat[:,0] 
Y_dat = dat[:,1] 
Z_dat = dat[:,2] 
C_dat = dat[:,3] 
ax1 = fig.add_subplot(111, projection='3d') 
for color in np.unique(C_dat): 
    X, Y, Z, C = np.array([]), np.array([]), np.array([]), np.array([]) 
    for i in range(len(X_dat)): 
     if C_dat[i]==color: 
      X = np.append(X,X_dat[i]) 
      Y = np.append(Y,Y_dat[i]) 
      Z = np.append(Z,Z_dat[i]) 
      C = np.append(C,C_dat[i]) 

    xi = np.linspace(X.min(),X.max(),100) 
    yi = np.linspace(Y.min(),Y.max(),100) 

    zi = griddata((X, Y), Z, (xi[None,:], yi[:,None]), method='cubic') 
    ci = griddata((X, Y), C, (xi[None,:], yi[:,None]), method='cubic') 

    xig, yig = np.meshgrid(xi, yi) 
    surf = ax1.plot_surface(xig, yig, zi,facecolors=cm.rainbow(ci), alpha = 0.7) 

xi = np.linspace(X_dat.min(),X_dat.max(),100) 
yi = np.linspace(Y_dat.min(),Y_dat.max(),100) 
ci = griddata((X_dat, Y_dat), C_dat, (xi[None,:], yi[:,None]), method='cubic') 
m = cm.ScalarMappable(cmap=cm.rainbow) 
m.set_array(ci) 
col = plt.colorbar(m) 
plt.show() 

enter image description here (должна быть красная плоскость)

+1

Редактирование вопрос, как это аннулирует ответ (ов) уже дали. В следующий раз было бы лучше задать новый вопрос. –

+0

@tom Я действительно думал, что код, который я разместил, был MCVE – kilojoules

+0

@tom Но я сгенерировал файл в коде – kilojoules

ответ

3

переместить линию

ax1 = fig.add_subplot(111, projection='3d') 

вне цикла for color in.... Воссоздавая осей каждой итерации, вы скрываете ранее созданные поверхности


EDIT (ответить на второй вопрос о цветовых карт)

Вы должны normalise данные. В настоящее время у вас есть facecolors в диапазоне от 0 до 0,6, поэтому, когда вы подаете максимум (0,6) до cm.rainbow, вы получаете зеленый, а не красный (так как он ожидает диапазон от 0 до 1).

Вот модифицированный сценарий, который, я думаю, работает так, как должен. Мы используем Normalise от matplotlib.colors с vmin и vmax, определенными из ваших данных C_dat. Затем используйте facecolors=cm.rainbow(norm(ci)), чтобы установить цвета ваших поверхностей.

Вы также хотите установить массив вашего ScalarMappable, используя значения в C_dat, поэтому нам не нужно снова использовать griddata.

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

dat = open('ex.csv', 'w') 
dat.write('x,y,z,c\n') 
for x in range(20): 
    for y in range(20): 
     for c in range(0,7): 
      dat.write(','.join([str(s) for s in [x,y,x+y+c,c/10.0,'\n']])) 
dat.close() 

fig = matplotlib.pyplot.gcf() 
dat = np.genfromtxt('ex.csv', delimiter=',',skip_header=1) 
X_dat = dat[:,0] 
Y_dat = dat[:,1] 
Z_dat = dat[:,2] 
C_dat = dat[:,3] 

# Create a Normalize instance. 
norm = colors.Normalize(vmin=C_dat.min(),vmax=C_dat.max()) 

ax1 = fig.add_subplot(111, projection='3d') 
for color in np.unique(C_dat): 
    X, Y, Z, C = np.array([]), np.array([]), np.array([]), np.array([]) 
    for i in range(len(X_dat)): 
     if C_dat[i]==color: 
      X = np.append(X,X_dat[i]) 
      Y = np.append(Y,Y_dat[i]) 
      Z = np.append(Z,Z_dat[i]) 
      C = np.append(C,C_dat[i]) 

    xi = np.linspace(X.min(),X.max(),100) 
    yi = np.linspace(Y.min(),Y.max(),100) 

    zi = griddata((X, Y), Z, (xi[None,:], yi[:,None]), method='cubic') 
    ci = griddata((X, Y), C, (xi[None,:], yi[:,None]), method='cubic') 

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

    # Note the use of norm in the facecolors option 
    surf = ax1.plot_surface(xig, yig, zi,facecolors=cm.rainbow(norm(ci)), alpha = 0.7) 

m = cm.ScalarMappable(cmap=cm.rainbow) 
m.set_array(np.unique(C_dat)) 

col = plt.colorbar(m) 

plt.show() 

enter image description here

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