如果我在球坐标中有与给定(theta,phi)点相对应的数值数组,如何在球体表面上绘制密度图?我已经找到了如何构建一个球体,例如Bloch sphere或plotting on a sphere。第一个例子非常好看 - 需要轴和热图。
答案 0 :(得分:6)
如果你继承Bloch
QuTip
类,并改变它绘制球体的方式,你可以绘制密度图并保留它创建的所有其他框架。
取matplotlib surface_plot
examples,改变Bloch
班级'绘图功能有效。将它放在你自己的子类中可以防止你破坏库。
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()
如果您想提高分辨率,只需更改plot_*
BlochDensity
函数内的linspace中的数字。