球体上的密度图 Python
density plot on a sphere Python
如果我有对应于球坐标中给定 (theta,phi) 点的值数组,如何在球体表面绘制密度图?我已经找到了如何构建一个球体,例如Bloch sphere or plotting on a sphere。第一个示例非常漂亮 - 需要轴和热图。
如果你子class Bloch
class of QuTip
,并改变它绘制球体的方式,你可以绘制密度图并保留所有其他它创建的框架。
采用 matplotlib surface_plot
examples 并更改 Bloch
class' 绘图功能有效。把它放在你自己的子目录中class 可以防止你盗用图书馆。
from qutip import Bloch
from math import sqrt, sin, cos, pi
from colorsys import hsv_to_rgb
from numpy import linspace, outer, ones, sin, cos, arccos, arctan2, size, empty
class BlochDensity(Bloch):
def plot_back(self):
# back half of sphere
u = linspace(0, pi, 25)
v = linspace(0, pi, 25)
x = outer(cos(u), sin(v))
y = outer(sin(u), sin(v))
z = outer(ones(size(u)), cos(v))
colours = empty(x.shape, dtype=object)
for i in range(len(x)):
for j in range(len(y)):
theta = arctan2(y[i,j], x[i,j])
phi = arccos(z[i,j])
colours[i,j] = self.density(theta, phi)
self.axes.plot_surface(x, y, z, rstride=1, cstride=1,
facecolors=colours,
alpha=self.sphere_alpha,
linewidth=0, antialiased=True)
# wireframe
self.axes.plot_wireframe(x, y, z, rstride=5, cstride=5,
color=self.frame_color,
alpha=self.frame_alpha)
# equator
self.axes.plot(1.0 * cos(u), 1.0 * sin(u), zs=0, zdir='z',
lw=self.frame_width, color=self.frame_color)
self.axes.plot(1.0 * cos(u), 1.0 * sin(u), zs=0, zdir='x',
lw=self.frame_width, color=self.frame_color)
def plot_front(self):
# front half of sphere
u = linspace(-pi, 0, 25)
v = linspace(0, pi, 25)
x = outer(cos(u), sin(v))
y = outer(sin(u), sin(v))
z = outer(ones(size(u)), cos(v))
colours = empty(x.shape, dtype=object)
for i in range(len(x)):
for j in range(len(y)):
theta = arctan2(y[i,j], x[i,j])
phi = arccos(z[i,j])
colours[i,j] = self.density(theta, phi)
self.axes.plot_surface(x, y, z, rstride=1, cstride=1,
facecolors=colours,
alpha=self.sphere_alpha,
linewidth=0, antialiased=True)
# wireframe
self.axes.plot_wireframe(x, y, z, rstride=5, cstride=5,
color=self.frame_color,
alpha=self.frame_alpha)
# equator
self.axes.plot(1.0 * cos(u), 1.0 * sin(u),
zs=0, zdir='z', lw=self.frame_width,
color=self.frame_color)
self.axes.plot(1.0 * cos(u), 1.0 * sin(u),
zs=0, zdir='x', lw=self.frame_width,
color=self.frame_color)
我在这里所做的是让绘图部分调用 BlochDensity
的函数:self.density(theta, phi)
- 我还没有定义。
创建 BlochDensity
对象后,您需要创建该函数,即 theta, phi
到您的密度的映射。我建议使用 SciPy's 2D interpolation 创建函数,如下所示:
from scipy.interpolate import interp2d
from numpy.random import rand
b = BlochDensity()
b.sphere_alpha=0.5
thetas, phis = linspace(-pi,pi,10), linspace(0,pi,10)
density = rand(len(thetas), len(phis))
#scale density to a maximum of 1
density /= density.max()
interpolated_density = interp2d(thetas, phis, density)
def f(theta, phi):
return hsv_to_rgb(interpolated_density(theta,phi), 1, 1)
b.density = f
b.show()
b.density = f
b.show()
如果你想增加分辨率,那么只需更改 BlochDensity
的 plot_*
函数内的 linspace 中的数字即可。
如果我有对应于球坐标中给定 (theta,phi) 点的值数组,如何在球体表面绘制密度图?我已经找到了如何构建一个球体,例如Bloch sphere or plotting on a sphere。第一个示例非常漂亮 - 需要轴和热图。
如果你子class Bloch
class of QuTip
,并改变它绘制球体的方式,你可以绘制密度图并保留所有其他它创建的框架。
采用 matplotlib surface_plot
examples 并更改 Bloch
class' 绘图功能有效。把它放在你自己的子目录中class 可以防止你盗用图书馆。
from qutip import Bloch
from math import sqrt, sin, cos, pi
from colorsys import hsv_to_rgb
from numpy import linspace, outer, ones, sin, cos, arccos, arctan2, size, empty
class BlochDensity(Bloch):
def plot_back(self):
# back half of sphere
u = linspace(0, pi, 25)
v = linspace(0, pi, 25)
x = outer(cos(u), sin(v))
y = outer(sin(u), sin(v))
z = outer(ones(size(u)), cos(v))
colours = empty(x.shape, dtype=object)
for i in range(len(x)):
for j in range(len(y)):
theta = arctan2(y[i,j], x[i,j])
phi = arccos(z[i,j])
colours[i,j] = self.density(theta, phi)
self.axes.plot_surface(x, y, z, rstride=1, cstride=1,
facecolors=colours,
alpha=self.sphere_alpha,
linewidth=0, antialiased=True)
# wireframe
self.axes.plot_wireframe(x, y, z, rstride=5, cstride=5,
color=self.frame_color,
alpha=self.frame_alpha)
# equator
self.axes.plot(1.0 * cos(u), 1.0 * sin(u), zs=0, zdir='z',
lw=self.frame_width, color=self.frame_color)
self.axes.plot(1.0 * cos(u), 1.0 * sin(u), zs=0, zdir='x',
lw=self.frame_width, color=self.frame_color)
def plot_front(self):
# front half of sphere
u = linspace(-pi, 0, 25)
v = linspace(0, pi, 25)
x = outer(cos(u), sin(v))
y = outer(sin(u), sin(v))
z = outer(ones(size(u)), cos(v))
colours = empty(x.shape, dtype=object)
for i in range(len(x)):
for j in range(len(y)):
theta = arctan2(y[i,j], x[i,j])
phi = arccos(z[i,j])
colours[i,j] = self.density(theta, phi)
self.axes.plot_surface(x, y, z, rstride=1, cstride=1,
facecolors=colours,
alpha=self.sphere_alpha,
linewidth=0, antialiased=True)
# wireframe
self.axes.plot_wireframe(x, y, z, rstride=5, cstride=5,
color=self.frame_color,
alpha=self.frame_alpha)
# equator
self.axes.plot(1.0 * cos(u), 1.0 * sin(u),
zs=0, zdir='z', lw=self.frame_width,
color=self.frame_color)
self.axes.plot(1.0 * cos(u), 1.0 * sin(u),
zs=0, zdir='x', lw=self.frame_width,
color=self.frame_color)
我在这里所做的是让绘图部分调用 BlochDensity
的函数:self.density(theta, phi)
- 我还没有定义。
创建 BlochDensity
对象后,您需要创建该函数,即 theta, phi
到您的密度的映射。我建议使用 SciPy's 2D interpolation 创建函数,如下所示:
from scipy.interpolate import interp2d
from numpy.random import rand
b = BlochDensity()
b.sphere_alpha=0.5
thetas, phis = linspace(-pi,pi,10), linspace(0,pi,10)
density = rand(len(thetas), len(phis))
#scale density to a maximum of 1
density /= density.max()
interpolated_density = interp2d(thetas, phis, density)
def f(theta, phi):
return hsv_to_rgb(interpolated_density(theta,phi), 1, 1)
b.density = f
b.show()
b.density = f
b.show()
如果你想增加分辨率,那么只需更改 BlochDensity
的 plot_*
函数内的 linspace 中的数字即可。