簡體   English   中英

如何在顏色條上繪制散點圖?

[英]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)

陰謀:

cbar0

我們需要一把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()

陰謀:

cbar1

您還可以在 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()

陰謀:

cbar2

與 y:

陰謀:

cbar3

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM