Skip to content

Missing sphere in Bloch sphere animation example using Matplotlib Axes3D #2156

@ericswitzer

Description

@ericswitzer

Bug Description

I attempted to recreate this animation of the Bloch sphere using the instructions in the Plotting on the Bloch Sphere/Directly Generating an Animation section of the user guide. Using Matplotlib 3.4.3 gives a warning,

MatplotlibDeprecationWarning: Axes3D(fig) adding itself to the figure is deprecated since 3.4. Pass the keyword argument auto_add_to_figure=False and use fig.add_axes(ax) to suppress this warning. The default value of auto_add_to_figure will change to False in mpl3.5 and True values will no longer work in 3.6. This is consistent with other Axes classes.

The movie is produced fine. If I use Matplotlib 3.7.1, the movie file contains a white background and no drawn Bloch sphere; see here.

This issue appears to be fixed by modifying the line ax = Axes3D(fig, azim=-40, elev=30) in the example to ax = fig.add_subplot(111, projection="3d", elev=30, azim=-40).

Code to Reproduce the Bug

import numpy as np
import qutip
from matplotlib import pyplot, animation
from mpl_toolkits.mplot3d import Axes3D

def qubit_integrate(w, theta, gamma1, gamma2, psi0, tlist):
    # operators and the hamiltonian
    sx = qutip.sigmax()
    sy = qutip.sigmay()
    sz = qutip.sigmaz()
    sm = qutip.sigmam()
    H = w * (np.cos(theta) * sz + np.sin(theta) * sx)
    # collapse operators
    c_op_list = []
    n_th = 0.5 # temperature
    rate = gamma1 * (n_th + 1)
    if rate > 0.0: c_op_list.append(np.sqrt(rate) * sm)
    rate = gamma1 * n_th
    if rate > 0.0: c_op_list.append(np.sqrt(rate) * sm.dag())
    rate = gamma2
    if rate > 0.0: c_op_list.append(np.sqrt(rate) * sz)
    # evolve and calculate expectation values
    output = qutip.mesolve(H, psi0, tlist, c_op_list, [sx, sy, sz])
    return output.expect[0], output.expect[1], output.expect[2]

## calculate the dynamics
w     = 1.0 * 2 * np.pi  # qubit angular frequency
theta = 0.2 * np.pi      # qubit angle from sigma_z axis (toward sigma_x axis)
gamma1 = 0.5             # qubit relaxation rate
gamma2 = 0.2             # qubit dephasing rate
# initial state
a = 1.0
psi0 = (a*qutip.basis(2, 0) + (1-a)*qutip.basis(2, 1))/np.sqrt(a**2 + (1-a)**2)
tlist = np.linspace(0, 4, 250)
#expectation values for ploting
sx, sy, sz = qubit_integrate(w, theta, gamma1, gamma2, psi0, tlist)

fig = pyplot.figure()
ax = Axes3D(fig, azim=-40, elev=30)
sphere = qutip.Bloch(axes=ax)

def animate(i):
   sphere.clear()
   sphere.add_vectors([np.sin(theta), 0, np.cos(theta)])
   sphere.add_points([sx[:i+1], sy[:i+1], sz[:i+1]])
   sphere.make_sphere()
   return ax

def init():
   sphere.vector_color = ['r']
   return ax

ani = animation.FuncAnimation(fig, animate, np.arange(len(sx)),
                              init_func=init, blit=False, repeat=False)
ani.save('bloch_sphere.mp4', fps=20)

Code Output

No response

Expected Behaviour

An animated Bloch sphere similar to the animation on the user guide here.

Your Environment

QuTiP Version:      4.7.1
Numpy Version:      1.23.5
Scipy Version:      1.10.1
Cython Version:     None
Matplotlib Version: 3.7.1
Python Version:     3.11.2
Number of CPUs:     12
BLAS Info:          INTEL MKL
OPENMP Installed:   False
INTEL MKL Ext:      True
Platform Info:      Linux (x86_64)

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions