将相同的颜色图和颜色条应用于多个 3D 图
Impose same colormap and colorbar to multiple 3D plot
目标是输出两个不同的 3D 图 (plot_surface
),以 "fair" 的方式为表面 (facecolors
) 提供特定颜色,即使用相同的颜色比例对于两个图形(固定相同的 x、y 和 z 轴,但这很容易)。此外,颜色条必须相同(即相同的刻度和范围)。换句话说,假设在图 1 中,(任意)值 8 与深红色相关联。然后,还必须申请图 2。请注意,在示例中,两个图形的 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)
如您所见,存在两个问题:
- 尽管 V1 和 V2 不同,但两个表面的颜色相同(实际上我应用了线性缩放从 V1 获得 V2)。
- 颜色条具有不同的值范围。
好处是颜色条将所有图形中的相同颜色与相同值相关联。如何解决前两个问题?
在循环中调用 m.set_array(V2)
。所以都使用 V2
作为数组;因此它们是相同的。
它应该是你应该使用的 lopp 变量 V
:
m.set_array(V)
我想我已经为您提供了 来规范化 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()
目标是输出两个不同的 3D 图 (plot_surface
),以 "fair" 的方式为表面 (facecolors
) 提供特定颜色,即使用相同的颜色比例对于两个图形(固定相同的 x、y 和 z 轴,但这很容易)。此外,颜色条必须相同(即相同的刻度和范围)。换句话说,假设在图 1 中,(任意)值 8 与深红色相关联。然后,还必须申请图 2。请注意,在示例中,两个图形的 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)
如您所见,存在两个问题:
- 尽管 V1 和 V2 不同,但两个表面的颜色相同(实际上我应用了线性缩放从 V1 获得 V2)。
- 颜色条具有不同的值范围。
好处是颜色条将所有图形中的相同颜色与相同值相关联。如何解决前两个问题?
在循环中调用 m.set_array(V2)
。所以都使用 V2
作为数组;因此它们是相同的。
它应该是你应该使用的 lopp 变量 V
:
m.set_array(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()