带有颜色图的 3D 图 - Python

3D Plot with a colormap - Python

我正在尝试制作一个显示 voltage vs. temp vs. power 的 3D 曲面图,并将每个点的颜色缩放到另一个值数组,已知作为 bifurWidth.

下面是我的代码。

我的代码有问题:

  1. 我无法使用 loadtxt 为 'bifurWidth' numpy.ndarray 生成我的代码 运行。本例中的错误是 Color array must be two-dimensional。但是,如果我使用 np.arange() 生成一组虚拟的 bifurWidth 值,它 运行。为什么当两者都是 numpy.ndarray 时会发生这种情况?
  2. 对于 3D 曲面图,我不知道如何让这个工作正常,图例可见。

有什么想法吗?

这是我的代码:

from glob import glob
from pylab import *
import numpy as np
from matplotlib import cm

import os

fs = 22

# Import data.
voltage = np.loadtxt('NonLorentzianData.txt',usecols=[0])
power = np.loadtxt('NonLorentzianData.txt',usecols=[1])
bifurWidth = arange(len(voltage))#np.loadtxt('LorentzianData.txt',usecols=[3])
temp = np.loadtxt('NonLorentzianData.txt',usecols=[4])
path = np.loadtxt('NonLorentzianData.txt',usecols=[5],dtype='S16')
c = np.abs(bifurWidth)

#Plot a 3D pot showing Temperature/Voltage/Power and intensity of colour showing bifurcation size.
fig = figure()
ax = fig.add_subplot(111, projection='3d')
cmhot = get_cmap("hot")
ax.scatter(voltage,temp,power,bifurWidth,s=35,c=c,cmap=cmhot)
ax.set_ylabel('Temperature (mK)',fontsize=fs)
ax.set_xlabel('Voltage (V)',fontsize=fs)
ax.set_zlabel('Power (dB)',fontsize=fs)
ax.set_title('Locating bifurcations.',fontsize=fs)
fig.tight_layout()
fig.set_size_inches(25,15)
fig.savefig('TEST.PNG',dpi=300)

首先,你说你想画一个曲面图,但在你的代码中你画了一个散点图。根据您对问题的其余描述,我假设您想制作一个散点图。

当我查看 scatterplot 函数的 documentation 时,我看到以下定义:

Axes3D.scatter(xs, ys, zs=0, zdir=u'z', s=20, c=u'b', depthshade=True, *args, **kwargs)

你称它为:

ax.scatter(voltage,temp,power,bifurWidth,s=35,c=c,cmap=cmhot)

这意味着第四个形式参数zdir将被调用,其值为bifurWidth。这不是你想要的,你想使用 zdir 的默认值并使用 bifurWidth 的绝对值作为颜色(你已经通过设置 c=c 完成的第二件事) .

因此,只需像这样删除 bifurWidth 参数:

ax.scatter(voltage,temp,power,s=35,c=c,cmap=cmhot)

这应该可以消除错误。

根据 this 问题的答案,3D 散点图不适用于图例,因此您需要制作一个不显示的虚拟图来创建图例。这是一个基于您的问题的相关示例,将图例添加到 3d 散点图:

from mpl_toolkits.mplot3d import Axes3D
from pylab import *
import numpy as np
from matplotlib import cm

# Fake data
(voltage, temp) = np.meshgrid(range(10), range(10))
power1 = np.random.rand(10,10)
power2 = np.random.rand(10,10)
bifurWidth1 = 100*np.random.rand(10.,10.)
bifurWidth2 = np.random.rand(10.,10.)

# Plot data
fig = figure()
ax = fig.add_subplot(111, projection='3d')
cm1 = get_cmap("Blues")
cm2 = get_cmap("Reds")
ax.scatter(voltage, temp, power1, c = bifurWidth1, s=35,  marker = 'o', cmap = cm1)
ax.scatter(voltage, temp, power2, c = bifurWidth2, s=35, marker = "^", cmap = cm2)

# Make legend
scatter1_proxy = matplotlib.lines.Line2D([0],[0], linestyle="none", c=cm1(128), marker = 'o')
scatter2_proxy = matplotlib.lines.Line2D([0],[0], linestyle="none", c=cm2(128), marker = '^')
ax.legend([scatter1_proxy, scatter2_proxy], ['label1', 'label2'], numpoints = 1)

# Label axes
fs = 12
ax.set_ylabel('Temperature (mK)',fontsize=fs)
ax.set_xlabel('Voltage (V)',fontsize=fs)
ax.set_zlabel('Power (dB)',fontsize=fs)
ax.set_title('Locating bifurcations.',fontsize=fs)

plt.show()