正如标题所说。我尝试了很多不同的方法来做到这一点。我有 4 个长度为 48 的向量。
X: [ 25 25 25 25 25 25 50 50 50 50 50 50 75 75 75 75 75 75
100 100 100 100 100 100 125 125 125 125 125 125 150 150 150 150 150 150
175 175 175 175 175 175 200 200 200 200 200 200]
Y: [ 100 250 500 1000 1500 2000 100 250 500 1000 1500 2000 100 250
500 1000 1500 2000 100 250 500 1000 1500 2000 100 250 500 1000
1500 2000 100 250 500 1000 1500 2000 100 250 500 1000 1500 2000
100 250 500 1000 1500 2000]
Z: [ 0.20900428 0.51286209 1.03853414 3.28220448 4.6407558 7.34891026
0.2765902 0.7604821 1.76022537 5.10049512 8.61249235 12.96447849
0.2623122 0.98286221 2.5040107 6.2533442 11.0721308 15.36910634
0.32121766 0.97078288 2.66376145 7.51123161 12.98652091 20.21016505
0.38653798 1.21371622 3.30200138 7.93705671 17.20774968 28.97923372
0.46758823 1.23861806 3.72943289 8.38099084 19.04535632 32.7009341
0.44258697 1.42894619 3.96008332 10.45831311 22.98130064 31.32277734
0.4507597 1.7036628 4.69553339 10.92697349 25.68610439 45.02457106]
C: [38.96 39.48 40.34 41.04 41.08 41.06 39.76 40.62 40.88 41.06 41.04 41.2
39.22 40.48 40.98 41.2 41.26 41.16 40.2 40.78 40.68 41.26 41.26 41.32
39.96 40.56 40.86 41.26 41.26 41.52 40.36 40.6 41.22 41.26 41.78 41.7
39.24 40.8 41.26 41.4 41.92 41.62 39.74 41.06 41.24 41.56 41.94 42.06]
这段代码
X = overall_results.num_generations.values
Y = overall_results.population_size.values
Z = overall_results.avg_time.values
C = overall_results.avg_reward.values
# note, C is not used as this is meant to be a fully working example
fig = plt.figure(figsize=(8,6))
ax = Axes3D(fig, auto_add_to_figure=False)
fig.add_axes(ax)
surf = ax.plot_trisurf(X, Y, Z, cmap=cm.jet, linewidth=.2)
ax.view_init(elev=5, azim=-140)
colorbar = fig.colorbar(surf, ax=ax, pad=0.1, shrink=.5, ticks=[5, 10, 15, 20, 25, 30], format="%d")
colorbar.ax.set_yticklabels(['<= 5', '10', '15', '20', '25', '>= 30'])
plt.title('GA Time Analysis by Population Size and Number of Generations')
plt.show()
产生这个数字
颜色映射到Z,我尝试合并C的各种方法都抛出错误。这也使用trisurf,并且,polycount非常低。
这段代码
X = overall_results.num_generations.values
Y = overall_results.population_size.values
Z = overall_results.avg_time.values
C = overall_results.avg_reward.values
# Define a finer grid for interpolation
new_X = np.linspace(X.min(), X.max(), 100)
new_Y = np.linspace(Y.min(), Y.max(), 100)
new_X, new_Y = np.meshgrid(new_X, new_Y)
# Perform interpolation
new_Z = griddata((X, Y), Z, (new_X, new_Y), method='linear')
# Create the 3D plot
fig = plt.figure(figsize=(8, 8))
ax = Axes3D(fig, auto_add_to_figure=False)
fig.add_axes(ax)
surf = ax.plot_surface(new_X, new_Y, new_Z, cmap=cm.jet, antialiased=True)
ticks = np.linspace(Z.min(), Z.max(), 10)
#ticks = [5, 10, 15, 20, 25, 30, 35, 40, 45]
colorbar = fig.colorbar(surf, ax=ax, pad=0.1, shrink=0.35, ticks=ticks, format="%d")
#colorbar.ax.set_yticklabels(['<= 5', '10', '15', '20', '25', '>= 30'])
ax.view_init(elev=8, azim=-150)
plt.title('GA Time Analysis by Population Size and Number of Generations')
ax.set_xlabel('Number of Generations', labelpad=12, fontsize=14)
ax.set_ylabel('Population Size', labelpad=12, fontsize=14)
ax.zaxis.set_rotate_label(False)
ax.set_zlabel('Running Time (seconds)', rotation=90, fontsize=14)
plt.show()
产生这个数字
一个更好看的图形,并使用plot_surface而不是trisurf。但同样,我无法使用 C 来设置颜色条。我看过
如何使用任意数据使用 matplotlib 制作 4D 绘图
带有表面梯度的 Color matplotlibplot_surface 命令
使用的库
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
from scipy.interpolate import griddata
from matplotlib.ticker import LinearLocator, FormatStrFormatter
from matplotlib.ticker import MaxNLocator
from matplotlib.colors import Normalize
现在,我可以创建一个散点图来完成我想要的操作,减去表面,就像这样
X = overall_results.num_generations.values
Y = overall_results.population_size.values
Z = overall_results.avg_time.values
C = overall_results.avg_reward.values
cmap = plt.get_cmap('jet') # You can choose any colormap you prefer
norm = Normalize(vmin=C.min(), vmax=C.max())
fig = plt.figure(figsize=(8,8))
ax = fig.add_subplot(111, projection='3d')
img = ax.scatter(X, Y, Z, c=C, s=100, cmap=cmap, norm=norm, alpha=1.0)
#plt.scatter(x, y, c=x, cmap=cmap, s=350, alpha=.7)
plt.xlabel('Average Reward', fontsize=14)
plt.ylabel('Running Time', fontsize=14)
cbar = fig.colorbar(img, pad=.1, shrink=.5)
cbar.set_label('Average Reward', fontsize=14, labelpad=10)
ax.view_init(elev=20, azim=-140)
plt.show()
产生这个数字
但我想要这种效果作为表面。
感谢 Gordon Stein 和 Caleb Vatral(去范德比尔特!),这是缺失的部分:
# Also color
new_C = griddata((X, Y), C, (new_X, new_Y), method='linear')
# Done to rescale it to show in color map, you likely need to change it
new_C = new_C - new_C.min()
new_C = cm.gist_rainbow(new_C / new_C.max())
surf = ax.plot_surface(new_X, new_Y, new_Z, facecolors=new_C, antialiased=True)
或者,
norm = (C - C.min()) / (C.max()-C.min())
new_C = griddata((X,Y), norm, (new_X, new_Y), method="linear")
colors = np.empty(new_X.shape, dtype=tuple)
for y in range(100):
for x in range(100):
colors[y, x] = cm.jet(new_C[x, y], )
surf = ax.plot_surface(new_X, new_Y, new_Z, facecolors=colors, antialiased=True)
通过一些颜色条操作,我们现在有了