Skip to content

Commit

Permalink
Add plotting recipes (#284)
Browse files Browse the repository at this point in the history
* update Project.toml for RecipesBase

* add RotationsRecipesBaseExt

* update plotting recipe for `Rotation{3}`

* fix ext dependency

* update for Julia v1.6

* add support recipe for `Rotation{2}`

* add tests for plotting recipe

* update axis color
  • Loading branch information
hyrodium authored Feb 6, 2024
1 parent 62da0eb commit d3fe01d
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
perf/benchmarkparams.json
Manifest.toml
docs/build
/test/out_plot
12 changes: 11 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,25 @@ version = "1.6.2"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Quaternions = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"

[weakdeps]
RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"

[extensions]
RotationsRecipesBaseExt = "RecipesBase"

[compat]
Aqua = "0.8"
BenchmarkTools = "1"
ForwardDiff = "0.10"
InteractiveUtils = "1"
LinearAlgebra = "1"
Plots = "1"
Quaternions = "0.5.3, 0.6, 0.7"
Random = "1"
RecipesBase = "1"
StaticArrays = "1.2.12"
Test = "1"
Unitful = "1"
Expand All @@ -27,11 +36,12 @@ BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
Quaternions = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"

[targets]
test = ["Aqua", "BenchmarkTools", "ForwardDiff", "InteractiveUtils", "LinearAlgebra", "Quaternions", "Random", "StaticArrays", "Test", "Unitful"]
test = ["Aqua", "BenchmarkTools", "ForwardDiff", "InteractiveUtils", "LinearAlgebra", "Plots", "Quaternions", "Random", "StaticArrays", "Test", "Unitful"]
76 changes: 76 additions & 0 deletions ext/RotationsRecipesBaseExt.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
module RotationsRecipesBaseExt

using RecipesBase
using Rotations
using StaticArrays

@recipe function f(R::Rotation{2}; origin=SVector(0,0), boxsize=0.2, axissize=1.0)
l = boxsize
L = axissize
e₁ = R[:,1]
e₂ = R[:,2]
ox, oy = origin
ps = vec([SVector(ox,oy)+R*SVector(x,y) for x in (-l,l), y in (-l,l)])
xs = getindex.(ps,1)
ys = getindex.(ps,2)
@series begin
primary := false
color := :red1
[e₁[1]*l+ox,e₁[1]*L+ox],[e₁[2]*l+oy,e₁[2]*L+oy]
end
@series begin
primary := false
color := :green1
[e₂[1]*l+ox,e₂[1]*L+ox],[e₂[2]*l+oy,e₂[2]*L+oy]
end
fill := true
delete!(plotattributes, :origin)
delete!(plotattributes, :boxsize)
delete!(plotattributes, :axissize)
xs[[1,3,4,2,1]], ys[[1,3,4,2,1]]
end

@recipe function f(R::Rotation{3}; origin=SVector(0,0,0), boxsize=0.2, axissize=1.0)
l = boxsize
L = axissize
e₁ = R[:,1]
e₂ = R[:,2]
e₃ = R[:,3]
ox, oy, oz = origin
ps = vec([SVector(ox,oy,oz)+R*SVector(x,y,z) for x in (-l,l), y in (-l,l), z in (-l,l)])
xs = getindex.(ps,1)
ys = getindex.(ps,2)
zs = getindex.(ps,3)
@series begin
primary := false
color := :red1
[e₁[1]*l+ox,e₁[1]*L+ox],[e₁[2]*l+oy,e₁[2]*L+oy],[e₁[3]*l+oz,e₁[3]*L+oz]
end
@series begin
primary := false
color := :green1
[e₂[1]*l+ox,e₂[1]*L+ox],[e₂[2]*l+oy,e₂[2]*L+oy],[e₂[3]*l+oz,e₂[3]*L+oz]
end
@series begin
primary := false
color := :blue1
[e₃[1]*l+ox,e₃[1]*L+ox],[e₃[2]*l+oy,e₃[2]*L+oy],[e₃[3]*l+oz,e₃[3]*L+oz]
end
seriestype := :mesh3d
connections := (
# Somehow 0-based indexing
# https://docs.juliaplots.org/latest/gallery/gr/generated/gr-ref047/
[1-1,1-1,1-1,1-1,1-1,1-1,8-1,8-1,8-1,8-1,8-1,8-1,],
[2-1,6-1,4-1,3-1,7-1,5-1,4-1,3-1,7-1,5-1,6-1,2-1,],
[6-1,5-1,2-1,4-1,3-1,7-1,3-1,7-1,5-1,6-1,2-1,4-1,],
)
# This connections can be 1-based indexing, but this throws an error on PythonPlot.
# https://discourse.julialang.org/t/how-to-plot-a-cube-in-3d-in-plots-jl/86919/2?u=hyrodium
# connections := [(1,2,6),(1,6,5),(1,4,2),(1,3,4),(1,7,3),(1,5,7),(8,4,3),(8,3,7),(8,7,5),(8,5,6),(8,6,2),(8,2,4)]
delete!(plotattributes, :origin)
delete!(plotattributes, :boxsize)
delete!(plotattributes, :axissize)
xs,ys,zs
end

end
4 changes: 4 additions & 0 deletions src/Rotations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,8 @@ export
# derivatives (names clash with ForwarDiff?)
#jacobian, hessian

if !isdefined(Base, :get_extension)
include("../ext/RotationsRecipesBaseExt.jl")
end

end # module
33 changes: 33 additions & 0 deletions test/plots.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
@testset "plot" begin
dir_out = joinpath(@__DIR__, "out_plot")
rm(dir_out; force=true, recursive=true)
mkpath(dir_out)

@testset "2d" begin
pl = plot(Angle2d(0.2); aspectratio=1)
plot!(pl, Angle2d(0.3); aspectratio=1)

path_img = joinpath(dir_out, "2d.png")
@test !isfile(path_img)
savefig(pl, path_img)
@test isfile(path_img)
end

@testset "3d" begin
N = 12
Random.seed!(42)
R1 = rand(QuatRotation)
R2 = rand(QuatRotation)
pl = plot(R1; linewidth=3, label="R1")
plot!(pl, R2; linewidth=3, label="R2", origin=(1,0,0))
for i in 2:N-1
t = i/N
plot!(pl, slerp(R1,R2,t); linewidth=3, label=nothing, origin=(t,0,0), boxsize=0.0, axissize=3/4)
end

path_img = joinpath(dir_out, "3d.png")
@test !isfile(path_img)
savefig(pl, path_img)
@test isfile(path_img)
end
end
2 changes: 2 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ using StaticArrays
using InteractiveUtils: subtypes
using Quaternions
using Aqua
using Plots
import Unitful
import Random

Expand All @@ -25,5 +26,6 @@ include("nearest_rotation.jl")
include("rotation_generator.jl")
include("elementary_functions.jl")
include("deprecated.jl")
include("plots.jl")

include(joinpath(@__DIR__, "..", "perf", "runbenchmarks.jl"))

0 comments on commit d3fe01d

Please sign in to comment.