Packages for Drawing and Graphics

What packages do I use for graphics? I found Cairo.jl and Graphics.jl the latter says it uses the former as a backend, but Graphics.jl is missing a lot of docstrings and looks abandoned.

1 Like

Compose.jl

using Colors, Compose
set_default_graphic_size(14cm,10cm)

petal=[[(0.4, 0.4), (0.4, 0.2), (0.5, 0.0)],[(0.6, 0.2), (0.6, 0.4), (0.5, 0.5)]]
petalf(θ::Float64) = (context(rotation=Rotation(θ, 0.5,0.5)),
    bezigon((0.5, 0.5), petal), fill(LCHuvA(70.,50., 360*θ/2π, 0.4)))

theta = range(Ď€/20, 2Ď€, step=2Ď€/10).-Ď€
img = compose(context(), petalf.(theta)...)

bezigon

5 Likes

https://github.com/JuliaGraphics/Luxor.jl

It’s fairly well documented.

4 Likes

Huge thanks to @cormullion for creating Luxor.jl!

Also, if you are curious about making animations of different kinds, check out Javis.jl

Here is an example of a fun animation @ric.cioffi contributed to Javis with!

7 Likes

I can’t find a tutorial or command list in the documentation.

The first example in the tutorial through an error, because it doesn’t recognise rectangle(), not a good sign.

Please provide a mwe, this works for me:

composition = compose(compose(context(), rectangle()), fill("tomato"))
	composition = compose(context(),
        (context(), circle(), fill("bisque")),
        (context(), rectangle(), fill("tomato")))
	composition |> SVG("tomato_bisque.svg")

circle not defined

That example also works for me, please show the error trace.


UndefVarError: circle not defined

top-level scope@Local: 2

[/quote]

I think the circle no recognized, was because I had Luxor loaded. now I get

MethodError: no method matching Compose.SVG(::IOStream, ::Measures.Length{:cx, Int64}, ::Measures.Length{:cy, Int64}, ::Bool, ::Symbol; ownedfile=true, filename="tomato_bisque.svg")

Closest candidates are:

Compose.SVG(::Any, ::Any, ::Any, ::Any, ::Any, !Matched::Any, !Matched::Any, !Matched::Any, !Matched::Any, !Matched::Any, !Matched::Any, !Matched::Any, !Matched::Any, !Matched::Any, !Matched::Any, !Matched::Any, !Matched::Any, !Matched::Any, !Matched::Any, !Matched::Any, !Matched::Any, !Matched::Any, !Matched::Any, !Matched::Any) at /home/brett/.julia/packages/Compose/AeWZ8/src/svg.jl:126 got unsupported keyword arguments "ownedfile", "filename"

Compose.SVG(::IO, !Matched::Measures.AbsoluteLength, !Matched::Measures.AbsoluteLength, ::Bool, ::Symbol; cached_out, id, indentation, property_stack, vector_properties, clippaths, batches, embobj, finished, ownedfile, filename, current_id, has_current_id, id_count, jsheader, jsmodules, scripts, withjs, panelcoords) at /home/brett/.julia/packages/Compose/AeWZ8/src/svg.jl:203

Compose.SVG(::IO, !Matched::Measures.AbsoluteLength, !Matched::Measures.AbsoluteLength, ::Bool) at /home/brett/.julia/packages/Compose/AeWZ8/src/svg.jl:203 got unsupported keyword arguments "ownedfile", "filename"

...

Compose.SVG(::String, ::Measures.Length{:cx, Int64}, ::Measures.Length{:cy, Int64}, ::Symbol)@svg.jl:274
top-level scope@Local: 5[inlined]

Without an example I can’t tell how you got that error, but using Absolute units works for me:

 composition |> SVG("tomato_bisque.svg", 10cm, 5cm)

Compose.jl and Luxor.jl have different philosophies. Compose.jl is a sophisticated high-level environment for making layouts using declarative graphics, and one of its jobs is to provide a backend for the much-loved Gadfly.jl plotting package. Luxor.jl is designed to be an easy to use procedural wrapper or “scripting language” for the powerful Cairo.jl graphics engine.

So @Mattriks’ elegant Compose.jl example above could be translated into a sequence of simple Luxor.jl instructions:

using Luxor, Colors

Drawing("A4", :svg)
origin()
for θ in range(π/20, 2π, step=2π/10) .- π
    setcolor(LCHuvA(70.,50., 360θ/2π, 0.4))
    petal = makebezierpath([O, Point(100, -50), Point(250, 0), 
           Point(250, 0), Point(100, 50)],  smoothing=0.8)
    @layer begin
        rotate(θ)
        drawbezierpath(petal, :fill)
    end
end
finish()
preview()

so slightly longer, slightly less “composed”.

Compose.jl will be better for layout-oriented work, particularly if “trees can be defined most tersely using S-expressions” (:arrow_upper_right:) floats your boat. But if you’d prefer to just bash out some simple instructions to get some basic graphics done, Luxor.jl can probably oblige.

8 Likes

Can you see this anywhere?

You need to click one of these first:

Screenshot 2021-01-29 at 10.34.30

1 Like

Thanks, I found it.