[英]How to plot scatter plot points on a colorbar?
我有一個評估函數的簡單曲面圖,我使用它在 3d 中繪制
surf = ax.plot_surface(xx, yy, zz)
對於 x、y 和 z 軸。
使用 surf 對象,我還創建了一個顏色條
fig.colorbar(surf, shrink=0.5, aspect=5)
然后我用一個簡單的散點函數在曲面圖上繪制點
plot = ax.scatter(xs=[], ys=[], zs=[], c="black", alpha=1.0, zorder=50)
這很好用,我得到了一個很好的曲面圖,上面畫了點。 我還在它旁邊看到一個顏色條,顯示評估函數梯度。
我現在想繪制與散點圖相同的點,但在顏色條上。 這樣,我想顯示點與所需值的接近程度。 我已經搜索了一段時間的文檔,但我對 matplotlib 很陌生,所以我不知道如何操作顏色條以顯示點。 如果你能幫我在顏色條上的一個隨機位置畫一個點,那么我會從那里拿它。
不確定這是否是您要查找的內容。
我改編了本教程中的示例並選擇了 20 個隨機點。 這些點分散在表面上。 並且它們的 z 值繪制在顏色條上。 為了不在一條直線上顯示所有值,隨機的 x 坐標用於在顏色條中定位。
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib.ticker import LinearLocator, FormatStrFormatter
import numpy as np
fig = plt.figure()
ax = fig.gca(projection='3d')
X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)
surf = ax.plot_surface(X, Y, Z, cmap=plt.cm.coolwarm,
linewidth=0, antialiased=True)
ax.set_zlim(-1.01, 1.01)
ax.zaxis.set_major_locator(LinearLocator(10))
ax.zaxis.set_major_formatter(FormatStrFormatter('%.02f'))
cbar = fig.colorbar(surf, shrink=0.8, aspect=8)
num_selected = 20
selection = (np.random.randint(0, 40, num_selected), np.random.randint(0, 40, num_selected))
plot = ax.scatter(xs=X[selection], ys=Y[selection], zs=Z[selection], c="black", alpha=1.0, zorder=50)
cbar.ax.scatter(x=np.random.uniform(*cbar.ax.set_xlim(), num_selected), y=Z[selection], c='k', s=5)
plt.show()
是的,可以在colorbar
上繪圖。 您只需要重新調整數據。
讓我們生成一些帶有點的表面,我將模擬優化器(隨機優化器)並在表面上繪制其步驟:
import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import axes3d
def zfun(x, y):
"""For computing Z"""
return x * np.cos(x) - y * np.cos(y)
# reproducibility first
np.random.seed(2020)
# Get some data
# define Space
X = np.linspace(-5, 5, 20)
Y = np.linspace(-5, 5, 20)
X, Y = np.meshgrid(X, Y)
Z = zfun(X, Y)
# Prepare fig
fw, fh = 10, 5
view = (65, 30)
fig = plt.figure(figsize=(fw, fh))
ax = fig.add_subplot(111, projection='3d')
ax.view_init(view[0], view[-1])
# Plot surface
surf = ax.plot_surface(X, Y, Z, cmap='jet', zorder=-1)
# Here is our test points: optimizer steps a kind of :)
x = np.random.choice(np.arange(-3, 3, 0.25), 7)
y = np.random.choice(np.arange(-5, 5, 0.25), 7)
z = zfun(x, y)
# I use plot3D, I think in 3D space it does better than scatter
# And you can connect all the dots to get a line
ax.plot3D(x, y, z, 'o-', c='k', markersize=5, zorder=3)
# Put a starting point
ax.plot3D([x[0]], [y[0]], [z[0]], 'o', c='r', markersize=5, zorder=3)
# Put the end
ax.plot3D([x[-1]], [y[-1]], [z[-1]], 'o', c='b', markersize=5, zorder=3)
# get some bars
cb = fig.colorbar(surf)
陰謀:
我們需要一把ax
在上面畫圖。 幸好colorbar
有這個功能:
print('ax' in dir(cb))
出去:
True
但是它有自己的 y 和 x 限制,它們的計算方式對我來說仍然是一個魔術,但似乎它們是由 z 最小值和最大值定義的,我們可以使用get_xlim()
和get_ylim()
方法查看它們:
print('cbar xlimits:', cb.ax.get_xlim())
print('cbar ylimits:', cb.ax.get_ylim())
print('Z min, max:', Z.min(), Z.max())
出去:
cbar xlimits: (-6.095315696318178, 6.095315696318178)
cbar ylimits: (-6.095315696318178, 6.095315696318178)
Z min, max: -6.5766626168117845 6.5766626168117845
因此,如果您想將 ath 放在顏色條上,則需要重新縮放它。 我們將使用這個函數:
def rescale(arr, min_=0, max_=1):
scale = (max_ - min_) / (arr.max() - arr.min())
arr = arr * scale + min_ - arr.min() * scale
return arr
現在我們可以在顏色條上繪圖。 讓我們首先繪制迭代順序:
...
cb = fig.colorbar(surf)
# we need this line now
cb.ax.set_aspect('auto')
# Put some labels
cb.ax.set_xlabel('iteration ->')
cb.ax.set_ylabel('z')
# get vals for rescale function
min_, max_ = cb.ax.get_xlim()
# generate and iter sequence [0, 1, 2, 3...]
iters = np.arange(len(z))
# rescale it
iters = rescale(iters, min_, max_)
# Now plot it!
cb.ax.scatter(iters, z, s=50, c='k', edgecolor='w') # add points
cb.ax.plot(iters, z, '--', c='k') # add line
cb.ax.plot(iters[0], z[0], 'o', c='r', markersize=5, label='start')
cb.ax.plot(iters[-1], z[-1], 'o', c='b', markersize=5, label='end')
cb.ax.legend()
陰謀:
您還可以在 cbar 上繪制 x 和 y 值,您只需要重新縮放它。 這是 cbar 的 x 軸上的 x 值和 y 軸上的 z 值:
...
cb = fig.colorbar(surf)
# we need this line now
cb.ax.set_aspect('auto')
# Put some labels
cb.ax.set_xlabel('x')
cb.ax.set_ylabel('z')
# get vals for rescale function
min_, max_ = cb.ax.get_xlim()
# rescale
x = rescale(x, min_, max_)
cb.ax.scatter(x, z, s=50, c='k', edgecolor='w') # add points
cb.ax.plot(x, z, '--', c='k') # add line
cb.ax.plot(x[0], z[0], 'o', c='r', markersize=5, label='start')
cb.ax.plot(x[-1], z[-1], 'o', c='b', markersize=5, label='end')
cb.ax.legend()
陰謀:
與 y:
陰謀:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.