From 9a8adb7e18096b064b10ebe2c20f53b5088c4f79 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Tue, 10 Jun 2025 22:15:09 +0800 Subject: [PATCH 1/4] improve `Bloch` alignment with qutip --- CHANGELOG.md | 3 +- .../users_guide/plotting_the_bloch_sphere.md | 3 +- ext/QuantumToolboxMakieExt.jl | 24 ++++++---------- src/visualization.jl | 28 ++++++++++--------- 4 files changed, 28 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 46997d6f5..020c8e43b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Introduce `Lanczos` solver for `spectrum`. ([#476]) - Add Bloch-Redfield master equation solver. ([#473]) -- Implement Bloch Sphere rendering and align style with qutip. ([#472], [#480], [#485], [#487]) +- Implement Bloch Sphere rendering and align style with qutip. ([#472], [#480], [#485], [#487], [#489]) - Add `Base.copy` method for `AbstractQuantumObject`. ([#486]) ## [v0.31.1] @@ -240,3 +240,4 @@ Release date: 2024-11-13 [#485]: https://github.com/qutip/QuantumToolbox.jl/issues/485 [#486]: https://github.com/qutip/QuantumToolbox.jl/issues/486 [#487]: https://github.com/qutip/QuantumToolbox.jl/issues/487 +[#489]: https://github.com/qutip/QuantumToolbox.jl/issues/489 diff --git a/docs/src/users_guide/plotting_the_bloch_sphere.md b/docs/src/users_guide/plotting_the_bloch_sphere.md index 273ad810c..59411831a 100644 --- a/docs/src/users_guide/plotting_the_bloch_sphere.md +++ b/docs/src/users_guide/plotting_the_bloch_sphere.md @@ -183,8 +183,9 @@ At the end of the last section we saw that the colors and marker shapes of the d |:----------|:----------------|:--------------------| | `b.font_color` | Color of axis labels and text | `"black"` | | `b.font_size` | Font size for labels | `20` | -| `b.frame_alpha` | Transparency of the wire frame | `0.1` | +| `b.frame_alpha` | Transparency of the wire frame | `0.2` | | `b.frame_color` | Color of the wire frame | `"gray"` | +| `b.frame_width` | Width of wire frame | `1.0` | | `b.point_default_color` | Default color cycle for points | `["blue", "red", "green", "#CC6600"]` | | `b.point_color` | List of colors for Bloch point markers to cycle through | `Union{Nothing,String}[]` | | `b.point_marker` | List of point marker shapes to cycle through | `[:circle, :rect, :diamond, :utriangle]` | diff --git a/ext/QuantumToolboxMakieExt.jl b/ext/QuantumToolboxMakieExt.jl index 88832a6a7..a0600170d 100644 --- a/ext/QuantumToolboxMakieExt.jl +++ b/ext/QuantumToolboxMakieExt.jl @@ -414,8 +414,8 @@ function _draw_bloch_sphere!(b::Bloch, lscene) # highlight circles for XY and XZ planes φ = range(0, 2π, length = 100) - lines!(lscene, [Point3f(cos(φi), sin(φi), 0) for φi in φ]; color = b.frame_color, linewidth = 1.0) # XY - lines!(lscene, [Point3f(cos(φi), 0, sin(φi)) for φi in φ]; color = b.frame_color, linewidth = 1.0) # XZ + lines!(lscene, [Point3f(cos(φi), sin(φi), 0) for φi in φ]; color = b.frame_color, linewidth = b.frame_width) # XY + lines!(lscene, [Point3f(cos(φi), 0, sin(φi)) for φi in φ]; color = b.frame_color, linewidth = b.frame_width) # XZ # other curves of longitude (with polar angle φ and azimuthal angle θ) φ_curve = range(0, 2π, 600) @@ -424,7 +424,7 @@ function _draw_bloch_sphere!(b::Bloch, lscene) x_line = radius * sin.(φ_curve) .* cos(θi) y_line = radius * sin.(φ_curve) .* sin(θi) z_line = radius * cos.(φ_curve) - lines!(lscene, x_line, y_line, z_line; color = b.frame_color, alpha = b.frame_alpha) + lines!(lscene, x_line, y_line, z_line; color = b.frame_color, alpha = b.frame_alpha, linewidth = b.frame_width) end # other curves of latitude (with polar angle φ and azimuthal angle θ) @@ -558,14 +558,11 @@ function _plot_points!(b::Bloch, lscene) end end if style in (:s, :m) - xs = raw_x[indperm] - ys = raw_y[indperm] - zs = raw_z[indperm] scatter!( lscene, - xs, - ys, - zs; + raw_x[indperm], + raw_y[indperm], + raw_z[indperm]; color = colors, markersize = b.point_size[mod1(k, length(b.point_size))], marker = marker, @@ -575,11 +572,8 @@ function _plot_points!(b::Bloch, lscene) ) elseif style == :l - xs = raw_x - ys = raw_y - zs = raw_z c = isa(colors, Vector) ? colors[1] : colors - lines!(lscene, xs, ys, zs; color = c, linewidth = 2.0, transparency = alpha < 1.0, alpha = alpha) + lines!(lscene, raw_x, raw_y, raw_z; color = c, transparency = alpha < 1.0, alpha = alpha) end end return nothing @@ -613,7 +607,7 @@ function _plot_lines!(b::Bloch, lscene) else :solid end - lines!(lscene, x, y, z; color = color, linewidth = 1.0, linestyle = linestyle) + lines!(lscene, x, y, z; color = color, linestyle = linestyle) end return nothing end @@ -643,7 +637,7 @@ function _plot_arcs!(b::Bloch, lscene) end t_range = range(0, θ, length = 100) arc_points = [Point3f((v1 * cos(t) + cross(n, v1) * sin(t))) for t in t_range] - lines!(lscene, arc_points; color = RGBAf(0.8, 0.4, 0.1, 0.9), linewidth = 2.0, linestyle = :solid) + lines!(lscene, arc_points; color = "blue", linestyle = :solid) end return nothing end diff --git a/src/visualization.jl b/src/visualization.jl index ad513dd35..c067efdd6 100644 --- a/src/visualization.jl +++ b/src/visualization.jl @@ -79,30 +79,31 @@ A structure representing a Bloch sphere visualization for quantum states. Availa ## Style properties -- `font_color::String`: Color of axis labels and text +- `font_color::String`: Color of axis labels and text. Default: `"black"` - `font_size::Int`: Font size for labels. Default: `20` -- `frame_alpha::Float64`: Transparency of the wire frame -- `frame_color::String`: Color of the wire frame +- `frame_alpha::Float64`: Transparency of the wire frame. Default: `0.2` +- `frame_color::String`: Color of the wire frame. Default: `"gray"` +- `frame_width::Float64` : Width of wire frame. Default: `1.0` ## Point properties -- `point_default_color::Vector{String}}`: Default color cycle for points -- `point_color::Vector{String}}`: List of colors for Bloch point markers to cycle through +- `point_default_color::Vector{String}}`: Default color cycle for points. Default: `["blue", "red", "green", "#CC6600"]` +- `point_color::Vector{String}}`: List of colors for Bloch point markers to cycle through. Default: `Union{Nothing,String}[]` - `point_marker::Vector{Symbol}}`: List of point marker shapes to cycle through. Default: `[:circle, :rect, :diamond, :utriangle]` -- `point_size::Vector{Int}}`: List of point marker sizes (not all markers look the same size when plotted) -- `point_style::Vector{Symbol}}`: List of marker styles -- `point_alpha::Vector{Float64}}`: List of marker transparencies +- `point_size::Vector{Int}}`: List of point marker sizes (not all markers look the same size when plotted). Default: `[5.5, 6.2, 6.5, 7.5]` +- `point_style::Vector{Symbol}}`: List of marker styles. Default: `Symbol[]` +- `point_alpha::Vector{Float64}}`: List of marker transparencies. Default: `Float64[]` ## Sphere properties -- `sphere_color::String`: Color of Bloch sphere surface +- `sphere_color::String`: Color of Bloch sphere surface. Default: `"#FFDDDD"` - `sphere_alpha::Float64`: Transparency of sphere surface. Default: `0.2` ## Vector properties -- `vector_color::Vector{String}`: Colors for vectors -- `vector_width::Float64`: Width of vectors -- `vector_arrowsize::Vector{Float64}`: Scales the size of the arrow head. The first two elements scale the radius (in `x/y` direction) and the last one is the length of the cone. +- `vector_color::Vector{String}`: Colors for vectors. Default: `["green", "#CC6600", "blue", "red"]` +- `vector_width::Float64`: Width of vectors. Default: `0.025` +- `vector_arrowsize::Vector{Float64}`: Scales the size of the arrow head. The first two elements scale the radius (in `x/y` direction) and the last one is the length of the cone. Default: `[0.07, 0.08, 0.08]` ## Layout properties @@ -124,8 +125,9 @@ A structure representing a Bloch sphere visualization for quantum states. Availa arcs::Vector{Vector{Vector{Float64}}} = Vector{Vector{Vector{Float64}}}() font_color::String = "black" font_size::Int = 20 - frame_alpha::Float64 = 0.1 + frame_alpha::Float64 = 0.2 frame_color::String = "gray" + frame_width::Float64 = 1.0 point_default_color::Vector{String} = ["blue", "red", "green", "#CC6600"] point_color::Vector{Union{Nothing,String}} = Union{Nothing,String}[] point_marker::Vector{Symbol} = [:circle, :rect, :diamond, :utriangle] From 66108ab9f396da820c9c26745db5c02d5ad5cfcb Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Tue, 10 Jun 2025 22:17:41 +0800 Subject: [PATCH 2/4] fix typo --- ext/QuantumToolboxMakieExt.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/QuantumToolboxMakieExt.jl b/ext/QuantumToolboxMakieExt.jl index a0600170d..3fcaaeee5 100644 --- a/ext/QuantumToolboxMakieExt.jl +++ b/ext/QuantumToolboxMakieExt.jl @@ -434,7 +434,7 @@ function _draw_bloch_sphere!(b::Bloch, lscene) x_ring = radius * sin(ϕ) .* cos.(θ_curve) y_ring = radius * sin(ϕ) .* sin.(θ_curve) z_ring = fill(radius * cos(ϕ), length(θ_curve)) - lines!(lscene, x_ring, y_ring, z_ring; color = b.frame_color, alpha = b.frame_alpha) + lines!(lscene, x_ring, y_ring, z_ring; color = b.frame_color, alpha = b.frame_alpha, linewidth = b.frame_width) end return nothing end From c29ea5e2b0f1f7cc214629936e07f69c4c3ec060 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Tue, 10 Jun 2025 23:32:35 +0800 Subject: [PATCH 3/4] fix typo and improve code coverage --- src/visualization.jl | 2 +- test/ext-test/cpu/makie/makie_ext.jl | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/visualization.jl b/src/visualization.jl index c067efdd6..273a9c21a 100644 --- a/src/visualization.jl +++ b/src/visualization.jl @@ -407,7 +407,7 @@ function add_states!(b::Bloch, states::Vector{<:QuantumObject}; kind::Symbol = : if kind == :vector add_vectors!(b, vecs) elseif kind == :point - add_points!(b, hcat(vecs...), kwargs...) + add_points!(b, hcat(vecs...); kwargs...) else throw(ArgumentError("Invalid kind = :$kind")) end diff --git a/test/ext-test/cpu/makie/makie_ext.jl b/test/ext-test/cpu/makie/makie_ext.jl index edcb7b192..64610bbb0 100644 --- a/test/ext-test/cpu/makie/makie_ext.jl +++ b/test/ext-test/cpu/makie/makie_ext.jl @@ -205,6 +205,7 @@ end @test false @info "Render threw unexpected error" exception=e end + b = Bloch() ψ₁ = normalize(basis(2, 0) + basis(2, 1)) ψ₂ = normalize(basis(2, 0) - im * basis(2, 1)) @@ -212,6 +213,7 @@ end add_line!(b, ψ₁, ψ₂; fmt = "r--") add_arc!(b, ψ₁, ψ₂) add_arc!(b, ψ₂, ψ₃, ψ₁) + add_states!(b, [ψ₂, ψ₃], kind = :point, meth = :l) try fig, lscene = render(b) @test !isnothing(fig) From 174c0dd07cb4e14d5cd519574fc3d1f6673b6d54 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Tue, 10 Jun 2025 23:34:45 +0800 Subject: [PATCH 4/4] format files --- test/ext-test/cpu/makie/makie_ext.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/ext-test/cpu/makie/makie_ext.jl b/test/ext-test/cpu/makie/makie_ext.jl index 64610bbb0..6f4b0c607 100644 --- a/test/ext-test/cpu/makie/makie_ext.jl +++ b/test/ext-test/cpu/makie/makie_ext.jl @@ -213,7 +213,7 @@ end add_line!(b, ψ₁, ψ₂; fmt = "r--") add_arc!(b, ψ₁, ψ₂) add_arc!(b, ψ₂, ψ₃, ψ₁) - add_states!(b, [ψ₂, ψ₃], kind = :point, meth = :l) + add_states!(b, [ψ₂, ψ₃], kind = :point, meth = :l) try fig, lscene = render(b) @test !isnothing(fig)