2017-03-21 50 views
1

facecolorsを使用して、定義済みの色でサーフェスを3Dでカラーリングしようとしています。ここでの問題は、cm.ScalarMappableはの色を正規化し、plt.cm.jetは正規化しないため、色とカラーバーの不一致があることです。手動でV(つまりV_normalized)を正規化しようとしましたが、結果はまだ正しくありません。実際には、Vの最高値は表面の隅にあるはずですが、実際には画像に反映されません。表面に色を補正する方法をプロットするには?matplotlib plot_surface用のカラーバー(ファクタ)

import numpy as np 
import pandas as pd 
import matplotlib.pyplot as plt 
from mpl_toolkits.mplot3d import Axes3D 
from matplotlib import cm 
# Create data. 
X = np.array([[ 50, 100, 150, 200, 250, 300, 350, 400, 450, 500], 
       [ 50, 100, 150, 200, 250, 300, 350, 400, 450, 500], 
       [ 50, 100, 150, 200, 250, 300, 350, 400, 450, 500], 
       [ 50, 100, 150, 200, 250, 300, 350, 400, 450, 500], 
       [ 50, 100, 150, 200, 250, 300, 350, 400, 450, 500], 
       [ 50, 100, 150, 200, 250, 300, 350, 400, 450, 500], 
       [ 50, 100, 150, 200, 250, 300, 350, 400, 450, 500], 
       [ 50, 100, 150, 200, 250, 300, 350, 400, 450, 500], 
       [ 50, 100, 150, 200, 250, 300, 350, 400, 450, 500]]) 
Y = np.array([[ 75, 75, 75, 75, 75, 75, 75, 75, 75, 75], 
       [125, 125, 125, 125, 125, 125, 125, 125, 125, 125], 
       [175, 175, 175, 175, 175, 175, 175, 175, 175, 175], 
       [225, 225, 225, 225, 225, 225, 225, 225, 225, 225], 
       [275, 275, 275, 275, 275, 275, 275, 275, 275, 275], 
       [325, 325, 325, 325, 325, 325, 325, 325, 325, 325], 
       [375, 375, 375, 375, 375, 375, 375, 375, 375, 375], 
       [425, 425, 425, 425, 425, 425, 425, 425, 425, 425], 
       [475, 475, 475, 475, 475, 475, 475, 475, 475, 475]]) 
Z = pd.DataFrame([[2.11, 2.14, 2.12, 2.10, 2.09, 2.08, 2.07, 2.07, 2.08, 2.05], 
        [2.01, 2.03, 1.99, 1.96, 1.95, 1.93, 1.90, 1.90, 1.92, 1.92], 
        [1.89, 1.90, 1.90, 1.94, 1.92, 1.89, 1.88, 1.87, 1.86, 1.86], 
        [1.79, 1.79, 1.75, 1.79, 1.77, 1.78, 1.78, 1.78, 1.79, 1.76], 
        [1.75, 1.77, 1.8, 1.79, 1.8, 1.77, 1.73, 1.73, 1.77, 1.77], 
        [1.72, 1.76, 1.77, 1.77, 1.79, 1.8, 1.78, 1.78, 1.74, 1.7], 
        [1.67, 1.66, 1.69, 1.7, 1.65, 1.62, 1.63, 1.65, 1.7, 1.69], 
        [1.64, 1.64, 1.61, 1.59, 1.61, 1.67, 1.71, 1.7, 1.72, 1.69], 
        [1.63, 1.63, 1.62, 1.67, 1.7, 1.67, 1.67, 1.69, 1.69, 1.68]], 
       index=np.arange(75, 525, 50), columns=np.arange(50, 525, 50)) 
V = pd.DataFrame([[ 7.53, 7.53, 7.53, 7.53, 7.53, 7.53, 7.53, 7.53, 7.53, 7.53], 
     [ 7.53, 7.53, 7.53, 7.53, 7.66, 8.09, 8.08, 8.05, 8.05, 8.05], 
     [ 7.53, 7.77, 8.08, 8.05, 8.19, 8.95, 8.93, 8.79,8.79, 8.62], 
     [ 8.95, 7.92, 8.95, 8.93, 8.62, 7.93, 8.96, 8.95, 9.09, 8.75], 
     [ 8.61, 8.95, 8.62, 8.61, 8.95, 8.93, 8.82, 9.42, 9.67, 8.48], 
     [ 9.23, 8.61, 8.95, 9.24, 9.42, 8.48, 8.47, 8.65, 8.92, 9.17], 
     [ 8.6 , 9.01, 9.66, 8.05, 9.42, 8.92, 8.81, 7.53, 7.53, 7.53], 
     [ 9.42, 9.25, 8.65, 8.92, 8.25, 7.97, 8.09, 8.49, 8.49, 7.58], 
     [ 10.15, 9.79, 9.1 , 9.35, 9.35, 9.35, 9.25, 9.3 , 9.3 , 8.19]], 
       index=np.arange(75, 525, 50), columns=np.arange(50, 525, 50)) 
# Create the figure, add a 3d axis, set the viewing angle 
# % matplotlib inline # If you are using IPython 
fig = plt.figure(figsize=[15,10]) 
ax = fig.add_subplot(111, projection='3d') 
ax.view_init(45,60) 
# Normalize in [0, 1] the DataFrame V that defines the color of the surface. 
V_normalized = (V - V.min().min()) 
V_normalized = V_normalized/V_normalized.max().max() 
# Plot 
ax.plot_surface(X, Y, Z, facecolors=plt.cm.jet(V_normalized)) 
ax.set_xlabel('x', fontsize=18) 
ax.set_ylabel('y', fontsize=18) 
ax.set_zlabel('z', fontsize=18) 
m = cm.ScalarMappable(cmap=cm.jet) 
m.set_array(V) 
plt.colorbar(m) 

enter image description here

答えて

1

あなたがmatplotlib.colors.Normalizeインスタンスを使用して正規化を簡素化するかもしれませんがあなたのプロットは、正しいです。

norm = matplotlib.colors.Normalize(vmin=V.min().min(), vmax=V.max().max()) 
ax.plot_surface(X, Y, Z, facecolors=plt.cm.jet(norm(V))) 
m = cm.ScalarMappable(cmap=plt.cm.jet, norm=norm) 
m.set_array([]) 
plt.colorbar(m) 

あなたはグリッド上10.15の最大値が表示されない理由のポイントは、別のものである:

つの次元に沿ってN点を有する、プロットは(N-1)顔を持っています。つまり、入力カラー配列の最後の行と列は単純にプロットされません。

これは、3x3マトリックスがプロットされ、2x2フェイスになる次の図に示されています。それらは、カラー配列内のそれぞれの値に従って色付けされ、その結果、第1の面は、配列内の第1の要素によって与えられる色を有する。最後の要素については、左に色付けする面はない。

enter image description here

このプロットを再現するコード:

import numpy as np 
import matplotlib.pyplot as plt 
from mpl_toolkits.mplot3d import Axes3D 
from matplotlib import cm 
import matplotlib.colors 

fig = plt.figure() 
ax = fig.add_subplot(111, projection='3d') 

x = np.arange(3) 
X,Y = np.meshgrid(x,x) 
Z = np.ones_like(X) 

V = np.array([[3,2,2],[1,0,3],[2,1,0]]) 

norm = matplotlib.colors.Normalize(vmin=0, vmax=3) 
ax.plot_surface(X, Y, Z, facecolors=plt.cm.jet(norm(V)), shade=False) 

m = cm.ScalarMappable(cmap=plt.cm.jet, norm=norm) 
m.set_array([]) 
plt.colorbar(m) 

ax.set_xlabel('x') 
ax.set_ylabel('y') 

plt.show() 
関連する問題