目标是输出两个不同的3D图(plot_surface
),为表面(facecolors
)提供特定的颜色,并在#34; fair"方式,即对两个图形使用相同比例的颜色(并且固定相同的x,y和z轴,但这很容易)。此外,颜色条必须相同(即相同的刻度和范围)。换句话说,假设在图1中,(任意)值8与暗红色相关联。然后,必须也适用于figure2。请注意,在示例X中,Y和Z对于两个图都是相同的,以使事情更简单。与表面相关的颜色有多大变化(即V1和V2)。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
# Generate data. V1 (V2) will determine the colours of the first figure1 (figure2)
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))
V1 = 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))
V2 = (V1-8) * 3 + 8
def my_plot3d(V):
# % matplotlib inline # Uncomment 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)
clrbar = plt.colorbar(m)
min_V = np.min([V1.min().min(), V2.min().min()])
max_V = np.max([V1.max().max(), V2.max().max()])
clrbar.set_clim(min_V, max_V)
my_plot3d(V1)
my_plot3d(V2)
如您所见,有两个问题:
好的一点是,colorbar将相同的颜色与所有数字中的相同值相关联。如何解决前两个问题?
答案 0 :(得分:1)
在循环中,您调用m.set_array(V2)
。所以都使用V2
作为数组;因此他们是一样的。
它应该是你应该使用的lopp变量V
:
m.set_array(V)
<小时/> 我想我已经为你提供了a solution来规范化V的值。当使用两个不同的数组进行着色时,你需要确保对它们使用相同的规范化,而不是单独规范化每个数组。
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
import matplotlib.colors
x = np.arange(3)
X,Y = np.meshgrid(x,x)
Z = np.ones_like(X)
V1 = np.array([[3,2,2],[1,0,3],[2,1,0]])
V2 = 1+ V1*1.6
def plot_array(V, vmin, vmax):
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
norm = matplotlib.colors.Normalize(vmin=vmin, vmax=vmax)
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')
plot_array(V1, np.min([V1.min(), V2.min()]), np.max([V1.max(), V2.max()]))
plot_array(V2, np.min([V1.min(), V2.min()]), np.max([V1.max(), V2.max()]))
plt.show()