I am trying to make a 3D surface plot showing voltage
vs. temp
vs. power
, and to scale the colour of each point to another array of values, known as bifurWidth
.
我试图制作一个3D表面图,显示电压与温度与功率的关系,并将每个点的颜色缩放到另一个值数组,称为bifurWidth。
Below is my code.
以下是我的代码。
Problems with my code:
我的代码问题:
- I cannot make my code run for a 'bifurWidth'
numpy.ndarray
generated usingloadtxt
. The error in this case isColor array must be two-dimensional
. However it does run if I generate a dummy set of bifurWidth values usingnp.arange()
. Why does this happen when both arenumpy.ndarray
s? - I have no idea how to get this working, with a legend visible, for a 3D surface plot.
我不能让我的代码运行使用loadtxt生成的'bifurWidth'numpy.ndarray。这种情况下的错误是Color数组必须是二维的。但是,如果我使用np.arange()生成一组虚拟的bifurWidth值,它会运行。当两者都是numpy.ndarrays时,为什么会这样?
对于3D曲面图,我不知道如何使用可见的图例来实现此功能。
Any ideas?
Here's my code:
这是我的代码:
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)
2 个解决方案
#1
First of all, you say you want to make a surface plot, but in your code you make a scatter plot. Based on the rest of your problem description I assume you want to make a scatter plot.
首先,你说你想制作一个曲面图,但是在你的代码中你制作一个散点图。根据您的问题描述的其余部分,我假设您要制作散点图。
When I look at the documentation of the scatterplot
function I see the following definition:
当我查看scatterplot函数的文档时,我看到以下定义:
Axes3D.scatter(xs, ys, zs=0, zdir=u'z', s=20, c=u'b', depthshade=True, *args, **kwargs)
You call it as:
你称之为:
ax.scatter(voltage,temp,power,bifurWidth,s=35,c=c,cmap=cmhot)
This means that the fourth formal parameter, zdir
, will be called with the value of bifurWidth
. This is not what you want, you want to use the default value of zdir
and to use the absolute value of bifurWidth
as the color (the second thing you already accomplish by setting c=c
).
这意味着将使用bifurWidth的值调用第四个形式参数zdir。这不是你想要的,你想使用zdir的默认值并使用bifurWidth的绝对值作为颜色(你通过设置c = c已经完成的第二件事)。
Therefore, just remove the bifurWidth
parameter like so:
因此,只需删除bifurWidth参数,如下所示:
ax.scatter(voltage,temp,power,s=35,c=c,cmap=cmhot)
This should get rid of the error.
这应该摆脱错误。
#2
According to the answer to this question 3D scatter plots won't work with legend so you need to make a dummy plot that isn't displayed to create the legend. Here's an example related based on your question that adds a legend to a 3d scatter plot:
根据这个问题的答案,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()
#1
First of all, you say you want to make a surface plot, but in your code you make a scatter plot. Based on the rest of your problem description I assume you want to make a scatter plot.
首先,你说你想制作一个曲面图,但是在你的代码中你制作一个散点图。根据您的问题描述的其余部分,我假设您要制作散点图。
When I look at the documentation of the scatterplot
function I see the following definition:
当我查看scatterplot函数的文档时,我看到以下定义:
Axes3D.scatter(xs, ys, zs=0, zdir=u'z', s=20, c=u'b', depthshade=True, *args, **kwargs)
You call it as:
你称之为:
ax.scatter(voltage,temp,power,bifurWidth,s=35,c=c,cmap=cmhot)
This means that the fourth formal parameter, zdir
, will be called with the value of bifurWidth
. This is not what you want, you want to use the default value of zdir
and to use the absolute value of bifurWidth
as the color (the second thing you already accomplish by setting c=c
).
这意味着将使用bifurWidth的值调用第四个形式参数zdir。这不是你想要的,你想使用zdir的默认值并使用bifurWidth的绝对值作为颜色(你通过设置c = c已经完成的第二件事)。
Therefore, just remove the bifurWidth
parameter like so:
因此,只需删除bifurWidth参数,如下所示:
ax.scatter(voltage,temp,power,s=35,c=c,cmap=cmhot)
This should get rid of the error.
这应该摆脱错误。
#2
According to the answer to this question 3D scatter plots won't work with legend so you need to make a dummy plot that isn't displayed to create the legend. Here's an example related based on your question that adds a legend to a 3d scatter plot:
根据这个问题的答案,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()