如何在色条上绘制散点图?

时间:2020-02-05 20:15:55

标签: python matplotlib scatter-plot colorbar mplot3d

对于评估函数,我有一个简单的表面图,我可以使用

在3d中进行绘制
surf = ax.plot_surface(xx, yy, zz)

用于x,y和z轴。

使用冲浪对象,我还创建了一个颜色栏

fig.colorbar(surf, shrink=0.5, aspect=5)

然后我使用简单的散点函数在表面图上绘制点

plot = ax.scatter(xs=[], ys=[], zs=[], c="black", alpha=1.0, zorder=50)

这很好用,我得到了一个不错的表面图,上面画了点。在它旁边也有一个颜色栏,显示评估函数渐变。

我现在想在散点图上绘制与散点图相同的点,但是在颜色栏上。这样,我想显示这些点与所需值的接近程度。我已经搜索了一段时间的文档,但是对于matplotlib来说我还很陌生,所以我不知道如何操作颜色条以显示要点。如果您可以帮助我在颜色栏上的任意位置绘制一个点,那么我将从那里开始。

2 个答案:

答案 0 :(得分:0)

不确定这是否是您要寻找的东西。

我在MIUI 10 doesn't let service start activity - Xiaomi Redmi Note修改了示例,并选择了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()

this tutorial

答案 1 :(得分:0)

是的,可以在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()和{{ 1}}方法:

get_ylim()

退出:

print('cbar xlimits:', cb.ax.get_xlim())
print('cbar ylimits:', cb.ax.get_ylim())
print('Z min, max:', Z.min(), Z.max())

因此,如果要在色条上放置amth,则需要重新缩放。 我们将使用此功能:

cbar xlimits: (-6.095315696318178, 6.095315696318178)
cbar ylimits: (-6.095315696318178, 6.095315696318178)
Z min, max: -6.5766626168117845 6.5766626168117845

现在,我们可以在颜色栏上进行绘图。让我们首先绘制一个迭代顺序:

def rescale(arr, min_=0, max_=1):
    scale = (max_ - min_) / (arr.max() - arr.min())
    arr = arr * scale + min_ - arr.min() * scale
    return arr

情节:

cbar1

您还可以在cbar上绘制x和y值,您需要重新缩放它。这是cbar的x轴上的x值,以及cbar的y轴上的z值:

...
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()

情节:

cbar2

使用y:

情节:

cbar3