Skip to content

Commit a391e96

Browse files
committed
some minor enhancements
1 parent e219680 commit a391e96

File tree

3 files changed

+96
-26
lines changed

3 files changed

+96
-26
lines changed

docs/src/users_guide/plotting_the_bloch_sphere.md

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,9 @@ fig, ax = render(b);
121121
fig
122122
```
123123

124-
## Add Another Set of Points
124+
Notice that, in contrast to states or vectors, each point remains the same color as the initial point. This is because adding multiple data points using [`add_points!`](@ref) is interpreted, by default, to correspond to a single data point (single qubit state) plotted at different times. This is very useful when visualizing the dynamics of a qubit. An example of this is given in the example . If we want to plot additional qubit states we can call additional [`add_points!`](@ref) functions:
125125

126-
If we want to plot additional qubit states we can call additional [`add_points!`](@ref) functions:
126+
## Add Another Set of Points
127127

128128
```@example Bloch_sphere_rendering
129129
xz = zeros(20);
@@ -134,3 +134,27 @@ add_points!(b, pnts);
134134
fig, ax = render(b);
135135
fig
136136
```
137+
138+
The color and shape of the data points is varied automatically by [`Bloch`](@ref). Notice how the color and point markers change for each set of data. Again, we have had to call add_points twice because adding more than one set of multiple data points is not supported by the add_points function.
139+
140+
What if we want to vary the color of our points. We can tell [`Bloch`](@ref) to vary the color of each point according to the colors listed in the `b.point_color`
141+
142+
```@example Bloch_sphere_rendering
143+
clear!(b)
144+
xp = cos.(th);
145+
yp = sin.(th);
146+
zp = zeros(20);
147+
pnts = [xp, yp, zp];
148+
add_points!(b, pnts, meth=:m);
149+
fig, ax = render(b);
150+
fig
151+
```
152+
153+
Now, the data points cycle through a variety of predefined colors. Now lets add another set of points, but this time we want the set to be a single color, representing say a qubit going from the ``|0\rangle`` state to the state in the `y-z` plane:
154+
155+
```@example Bloch_sphere_rendering
156+
pnts = [xz, yz, zz] ;
157+
add_points!(b, pnts);
158+
fig, ax = render(b);
159+
fig
160+
```

ext/QuantumToolboxMakieExt.jl

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -630,27 +630,62 @@ Plot all quantum state points on the Bloch sphere.
630630
Handles both scatter points and line traces based on style specifications.
631631
"""
632632
function _plot_points!(b::Bloch, ax)
633-
for (k, points) in enumerate(b.points)
633+
for k in 1:length(b.points)
634+
pts = b.points[k]
634635
style = b.point_style[k]
635-
color = b.point_color[k]
636636
alpha = b.point_alpha[k]
637-
marker = b.point_marker[(k-1)%length(b.point_marker)+1]
638-
x, y, z = points[2, :], -points[1, :], points[3, :]
639-
if style (:s, :m)
637+
marker = b.point_marker[mod1(k, length(b.point_marker))]
638+
N = size(pts, 2)
639+
640+
raw_x = pts[2, :]
641+
raw_y = -pts[1, :]
642+
raw_z = pts[3, :]
643+
644+
ds = vec(sqrt.(sum(abs2, pts; dims = 1)))
645+
if !all(isapprox.(ds, ds[1]; rtol = 1e-12))
646+
indperm = sortperm(ds)
647+
else
648+
indperm = collect(1:N)
649+
end
650+
this_color = b.point_color[k]
651+
if style == :m
652+
defaults = b.point_default_color
653+
L = length(defaults)
654+
times = ceil(Int, N / L)
655+
big_colors = repeat(b.point_default_color, times)[1:N]
656+
big_colors = big_colors[indperm]
657+
colors = big_colors
658+
else
659+
if this_color === nothing
660+
defaults = b.point_default_color
661+
colors = defaults[mod1(k, length(defaults))]
662+
else
663+
colors = this_color
664+
end
665+
end
666+
if style in (:s, :m)
667+
xs = raw_x[indperm]
668+
ys = raw_y[indperm]
669+
zs = raw_z[indperm]
640670
scatter!(
641671
ax,
642-
x,
643-
y,
644-
z;
645-
color = color,
646-
markersize = 6,
672+
xs,
673+
ys,
674+
zs;
675+
color = colors,
676+
markersize = b.point_size[mod1(k, length(b.point_size))],
647677
marker = marker,
648-
strokewidth = 0.05,
649-
transparency = alpha<1,
678+
transparency = alpha < 1.0,
650679
alpha = alpha,
680+
strokewidth = 0.0,
651681
)
682+
652683
elseif style == :l
653-
lines!(ax, x, y, z; color = color, linewidth = 2.0, transparency = alpha<1, alpha = alpha)
684+
xs = raw_x
685+
ys = raw_y
686+
zs = raw_z
687+
c = isa(colors, Vector) ? colors[1] : colors
688+
lines!(ax, xs, ys, zs; color = c, linewidth = 2.0, transparency = alpha < 1.0, alpha = alpha)
654689
end
655690
end
656691
end

src/visualization.jl

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,10 @@ A structure representing a Bloch sphere visualization for quantum states.
137137
frame_alpha::Float64 = 0.0
138138
frame_color::String = "white"
139139
frame_limit::Float64 = 1.5
140-
point_default_color::Vector{String} = ["blue", "red", "green", "orange", "cyan", "magenta", "yellow", "black"]
141-
point_color::Vector{String} = ["blue", "red", "green", "orange", "cyan", "magenta", "yellow", "black"]
140+
point_default_color::Vector{String} = ["blue", "red", "green", "orange"]
141+
point_color::Vector{Union{Nothing,String}} = Union{Nothing,String}[]
142142
point_marker::Vector{Symbol} = [:circle, :rect, :diamond, :utriangle]
143-
point_size::Vector{Float64} = [4.0, 4.8, 5.0, 6.0]
143+
point_size::Vector{Float64} = [5.0, 6.0, 7.0, 8.0]
144144
point_style::Vector{Symbol} = Symbol[]
145145
point_alpha::Vector{Float64} = Float64[]
146146
sphere_alpha::Float64 = 0.4
@@ -228,20 +228,28 @@ Add multiple points to the Bloch sphere visualization.
228228
- alpha=1.0: Transparency (1.0 = opaque, 0.0 = transparent)
229229
```
230230
"""
231-
function add_points!(b::Bloch, pnts::Matrix{<:Real}; meth::Symbol = :s, color = nothing, alpha = 1.0)
231+
function add_points!(
232+
b::Bloch,
233+
pnts::Matrix{<:Real};
234+
meth::Symbol = :s,
235+
color::Union{Nothing,String} = nothing,
236+
alpha::Float64 = 1.0,
237+
)
232238
if size(pnts, 1) != 3
233-
error("Points must be a 3×N matrix where columns are [x;y;z] points")
239+
error("Points must be a 3×N matrix where each column is [x; y; z]")
234240
end
235-
if meth [:s, :m, :l]
236-
error("meth must be :s, :m, or :l")
237-
end
238-
if meth == :s && size(pnts, 2) == 1
239-
pnts = hcat(pnts, pnts)
241+
if !(meth in (:s, :m, :l))
242+
error("`meth` must be :s, :m, or :l")
240243
end
241244
push!(b.points, convert(Matrix{Float64}, pnts))
242245
push!(b.point_style, meth)
243246
push!(b.point_alpha, alpha)
244-
return push!(b.point_color, color === nothing ? b.point_default_color[1] : color)
247+
if color === nothing
248+
push!(b.point_color, nothing)
249+
else
250+
push!(b.point_color, color)
251+
end
252+
return nothing
245253
end
246254

247255
@doc raw"""
@@ -324,6 +332,9 @@ Clear all graphical elements (points, vectors, lines, arcs) from the given Bloch
324332
"""
325333
function clear!(b::Bloch)
326334
empty!(b.points)
335+
empty!(b.point_color)
336+
empty!(b.point_style)
337+
empty!(b.point_alpha)
327338
empty!(b.vectors)
328339
empty!(b.lines)
329340
empty!(b.arcs)

0 commit comments

Comments
 (0)