Skip to content

Commit cadc18a

Browse files
TendonFFFcailixun
andauthored
Bloch anime (#519)
Co-authored-by: cailixun <cailixun23@gmail.com>
1 parent 13709a1 commit cadc18a

File tree

2 files changed

+93
-8
lines changed

2 files changed

+93
-8
lines changed

docs/src/users_guide/plotting_the_bloch_sphere.md

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,4 +211,63 @@ These properties can also be accessed via the `print` command:
211211
```@example Bloch_sphere_rendering
212212
b = Bloch()
213213
print(b)
214-
```
214+
```
215+
216+
## Animating with the Bloch sphere
217+
218+
The [`Bloch`](@ref) structure was designed from the outset to generate animations. To animate a set of vectors or data points, the basic idea is: plot the data at time ``t_1``, save the sphere, clear the sphere, plot data at ``t_2``, and so on. The easiest way to animate data on the Bloch sphere is to use the `record` function provided by [`Makie.jl`](https://docs.makie.org/stable/). We will demonstrate this functionality with the following example: the decay of a qubit on the Bloch sphere.
219+
220+
```@example Bloch_sphere_rendering
221+
# system parameters
222+
ω = 2π
223+
θ = 0.2π
224+
n_th = 0.5 # temperature
225+
γ1 = 0.5
226+
γ2 = 0.2
227+
228+
# operators and the Hamiltonian
229+
sx = sigmax()
230+
sy = sigmay()
231+
sz = sigmaz()
232+
sm = sigmam()
233+
H = ω * (cos(θ) * sz + sin(θ) * sx)
234+
235+
# collapse operators
236+
c_op_list = (
237+
√(γ1 * (n_th + 1)) * sm,
238+
√(γ1 * n_th) * sm',
239+
√γ2 * sz
240+
)
241+
242+
# solving evolution
243+
ψ0 = basis(2, 0)
244+
tlist = LinRange(0, 4, 250)
245+
sol = mesolve(H, ψ0, tlist, c_op_list, e_ops = (sx, sy, sz), progress_bar = Val(false))
246+
x = real(sol.expect[1,:])
247+
y = real(sol.expect[2,:])
248+
z = real(sol.expect[3,:])
249+
```
250+
251+
To animate a set of vectors or data points, we use the `record` function provided by [`Makie.jl`](https://docs.makie.org/stable/):
252+
253+
```@example Bloch_sphere_rendering
254+
b = Bloch()
255+
b.view = [50,30]
256+
257+
fig, lscene = render(b)
258+
259+
record(fig, "qubit_decay.mp4", eachindex(tlist), framerate = 20) do idx
260+
clear!(b)
261+
add_vectors!(b, [sin(θ), 0, cos(θ)])
262+
add_points!(b, [x[1:idx], y[1:idx], z[1:idx]])
263+
render(b, location = lscene)
264+
end
265+
nothing # hide
266+
```
267+
268+
```@raw html
269+
<video autoplay loop muted playsinline controls src="./qubit_decay.mp4" />
270+
```
271+
272+
!!! note
273+
Here, we set the keyword argument `location = lscene` in the last `render` function to update the existing Bloch sphere without creating new `Figure` and `LScene`. This is efficient when drawing animations.

ext/QuantumToolboxMakieExt.jl

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -337,14 +337,24 @@ Render the Bloch sphere visualization from the given [`Bloch`](@ref) object `b`.
337337
# Arguments
338338
339339
- `b::Bloch`: The Bloch sphere object containing states, vectors, and settings to visualize.
340-
- `location::Union{GridPosition,Nothing}`: The location of the plot in the layout. If `nothing`, the plot is created in a new figure. Default is `nothing`.
340+
- `location::Union{GridPosition,LScene,Nothing}`: The location of the plot in the layout or `Makie.LScene`
341+
341342
342343
# Returns
343344
344345
- A tuple `(fig, lscene)` where `fig` is the figure object and `lscene` is the LScene object used for plotting. These can be further manipulated or saved by the user.
346+
347+
# Notes
348+
349+
The keyword argument `location` can be in the either type:
350+
351+
- `Nothing` (default): Create a new figure and plot the Bloch sphere.
352+
- `GridPosition`: Plot the Bloch sphere in the specified location of the plot in the layout.
353+
- `LScene`: Update the existing Bloch sphere using new data and settings in `b::Bloch` without creating new `Figure` and `LScene` (efficient for drawing animation).
345354
"""
346355
function QuantumToolbox.render(b::Bloch; location = nothing)
347-
fig, lscene = _setup_bloch_plot!(b, location)
356+
fig, lscene = _setup_bloch_plot!(location)
357+
_setup_bloch_camara!(b, lscene)
348358
_draw_bloch_sphere!(b, lscene)
349359
_add_labels!(b, lscene)
350360

@@ -358,30 +368,46 @@ function QuantumToolbox.render(b::Bloch; location = nothing)
358368
end
359369

360370
raw"""
361-
_setup_bloch_plot!(b::Bloch, location) -> (fig, lscene)
371+
_setup_bloch_plot!(location) -> (fig, lscene)
362372
363373
Initialize the figure and `3D` axis for Bloch sphere visualization.
364374
365375
# Arguments
366-
- `b::Bloch`: Bloch sphere object containing view parameters
367-
- `location`: Figure layout position specification
376+
- `location`: Figure layout position specification, or directly `Makie.LScene` for update
368377
369378
# Returns
370379
- `fig`: Created Makie figure
371380
- `lscene`: Configured LScene object
372381
373382
Sets up the `3D` coordinate system with appropriate limits and view angles.
374383
"""
375-
function _setup_bloch_plot!(b::Bloch, location)
384+
function _setup_bloch_plot!(location)
376385
fig, location = _getFigAndLocation(location)
377386
lscene = LScene(location, show_axis = false, scenekw = (clear = true,))
387+
return fig, lscene
388+
end
389+
390+
function _setup_bloch_plot!(lscene::LScene)
391+
# this function only removes all existing Plots in lscene
392+
# it is useful for users to just update Bloch sphere without creating new figure and lscene (efficient for drawing animation)
393+
fig = lscene.parent
394+
empty!(lscene.scene.plots)
395+
return fig, lscene
396+
end
397+
398+
raw"""
399+
_setup_bloch_camara!(b::Bloch, lscene)
400+
401+
Setup the distance and viewing angle of the camara.
402+
"""
403+
function _setup_bloch_camara!(b::Bloch, lscene)
378404
length(b.view) == 2 || throw(ArgumentError("The length of `Bloch.view` must be 2."))
379405
cam3d!(lscene.scene, center = false)
380406
cam = cameracontrols(lscene)
381407
cam.fov[] = 12 # Set field of view to 12 degrees
382408
dist = 12 # Set distance from the camera to the Bloch sphere
383409
update_cam!(lscene.scene, cam, deg2rad(b.view[1]), deg2rad(b.view[2]), dist)
384-
return fig, lscene
410+
return nothing
385411
end
386412

387413
raw"""

0 commit comments

Comments
 (0)