【问题标题】:3D normal distribution scatter plot with 1D array as color map以 1D 数组为彩色图的 3D 正态分布散点图
【发布时间】:2020-09-23 06:52:35
【问题描述】:

我想创建颜色映射范围从 min(u), u =64 到 max(u), u=100 的 3d 散点图。 u 是一维数组

代码按预期工作,u 从中心增加 (x,y,z)=(0,0,0) 但颜色不正确,颜色渐变应根据 u 变化,从 min(u)到 max(u) 而不是取决于 x,y,z 坐标。 colorbar 也不正确(应该是 0 到 100)

fig = plt.figure(figsize = (8,6))
ax = fig.add_subplot(111, projection='3d')
ax.set_title('normal distribution')

#add the line/data in our plot
x = 18 * np.random.normal(size =500)
y = 18 * np.random.normal(size =500)
z = 18 * np.random.normal(size =500)

u = np.linspace(64, 100, 500)

norma = mpl.colors.Normalize(min(u), max(u))
color = np.linalg.norm([x,y,z], axis=0)
track = ax.scatter(x,y,z, s=35, c = color, alpha = 1, cmap='inferno', norm = norma)

plt.colorbar(track, label='color map', shrink=0.6)
fig = plt.figure(figsize = (8,6))
ax = fig.add_subplot(111, projection='3d')
ax.set_title('normal distribution')

the above code figure

当颜色图归一化为 vmin=min(u) 和 vmax=max(u) 时,颜色渐变会丢失,颜色图渐变值会沿 x、y、z 轴随机分布,而不是在有序数组中。 有人知道如何修复沿轴的颜色渐变,而 u 的中心位于 (0,0,0) 并带有正确的颜色条 (0-100)?

fig = plt.figure(figsize = (8,6))
ax = fig.add_subplot(111, projection='3d')
ax.set_title('normal distribution')

#add the line/data in our plot
x = 18 * np.random.normal(size =500)
y = 18 * np.random.normal(size =500)
z = 18 * np.random.normal(size =500)

u = np.linspace(100, 64, 500)

norma = mpl.colors.Normalize(vmin=0, vmax = 100)
color = np.linalg.norm([u], axis=0)
track = ax.scatter(x,y,z, s=35, c = color, alpha = 1, cmap='inferno', norm = norma)

plt.colorbar(track, label='color map', shrink=0.6)

The result of the second example

【问题讨论】:

  • 我是否理解正确,您想使用xyz 作为坐标并使用u 作为颜色?那么你的第一个例子是正确的。如果要标准化颜色,只需使用min(u)max(u) 作为Normalize() 的参数。
  • 感谢您的回答,我已经尝试了您的建议,但仍然在随机位置获取颜色,而不是从 min(u) 到 max(u) norma = mpl.colors.Normalize(vmin=min(u), vmax = max(u)
  • 啊,我想我现在明白你的问题了。您期望u 从中心增加。在这种情况下,warped 的答案应该可以正常工作。您刚刚将线性增加的u 分配给您的随机坐标。这就是为什么你有随机分布的颜色。
  • 好的,我在编辑问题后更好地解释了问题。实际上,我希望 u 从 (0,0,0) 坐标增加,但我在中心值 u=64 而不是 0。我是否更好地解释自己?我无法管理的主要事情是从 (x,y,z) = (0,0,0) 上绘制正态分布的散点图以及中心为 min(u) (u=64) 的颜色图, 和 max(u) , u=100。
  • @heather-by 所以你想创建一个半径为 18 的球体,以 0 为中心。球体由 500 个点组成。这些点呈正态分布,中心的密度最高。正确的?现在点的颜色应该取决于到中心的距离。中心的值为 64(黑色)。在球体的表面上,该值为 100(黄色)。这是正确的吗?

标签: python numpy matplotlib colormap


【解决方案1】:
x = 18 * np.random.normal(size =500)
y = 18 * np.random.normal(size =500)
z = 18 * np.random.normal(size =500)

# collect all data in array
data = np.array([x,y,z])

# center in a given dimension is the mean of all datapoints:
# reshape to allow easy subtraction
center = np.mean(data, axis=1).reshape(3,-1)
# for each datapoint, calculate distance to center and use as color value
color = np.linalg.norm(data - center, axis=0)

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

track = ax.scatter(x,y,z, s=35, c = color, alpha = 1, cmap='inferno')
plt.colorbar(track, label='color map', shrink=0.6)

【讨论】:

    【解决方案2】:

    我找到了this question,它似乎回答了您关于坐标的问题。如果您愿意,答案还显示了如何均匀分布坐标。

    获得坐标后,您可以将距中心的距离作为颜色值(就像他的回答中的翘曲一样)。我调整了距离以反映您的规格。这是生成的代码:

    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib.colors import Normalize
    from mpl_toolkits.mplot3d import Axes3D
    
    number_of_particles = 500
    sphere_radius = 18
    
    # create the particles
    radius = sphere_radius * np.random.uniform(0.0, 1.0, number_of_particles)
    theta = np.random.uniform(0., 1., number_of_particles) * 2 * np.pi
    phi = np.random.uniform(0., 1., number_of_particles) * 2 * np.pi
    x = radius * np.sin(theta) * np.cos(phi)
    y = radius * np.sin(theta) * np.sin(phi)
    z = radius * np.cos(theta)
    
    # collect all data in array
    data = np.array([x, y, z])
    
    # for each datapoint, calculate distance to center and use as color value
    color = radius
    color /= sphere_radius
    color = color * 36 + 64
    
    # initialize a figure with a plot
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    
    # add the points and the colorbar
    track = ax.scatter(x, y, z, s=35, c=color, alpha=1, cmap='inferno',
                       norm=Normalize(0, 100))
    plt.colorbar(track, label='color map', shrink=0.6)
    
    plt.show()
    

    我的结果如下所示:

    【讨论】:

    • omg,非常感谢您的详细回答!成功了。
    猜你喜欢
    • 2022-07-08
    • 1970-01-01
    • 2019-05-14
    • 1970-01-01
    • 1970-01-01
    • 2021-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多