Skip to content

Commit

Permalink
Merge pull request #11 from kunzaatko/savefig_argument_cascade
Browse files Browse the repository at this point in the history
feat: Argument calling cascade for `savefig`
  • Loading branch information
kunzaatko authored Jan 31, 2025
2 parents 1f06bde + 094bc14 commit df6d34d
Show file tree
Hide file tree
Showing 14 changed files with 899 additions and 172 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "MakieMaestro"
uuid = "c922e6f1-a74a-406e-9215-09b2647b2648"
authors = ["Martin Kunz <martinkunz@email.cz> and contributors"]
version = "0.1.0"
version = "0.2.0"

[deps]
CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0"
Expand Down
9 changes: 9 additions & 0 deletions docs/src/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Pages = ["reference.md"]
```@docs
savefig
figure_dir!
export_format!
```

```@raw html
Expand All @@ -37,6 +38,13 @@ MakieMaestro.get_themes
MakieMaestro.get_export_theme
MakieMaestro.get_formats
MakieMaestro.FunctionSpec
MakieMaestro.PathSpec
MakieMaestro.get_export_format
MakieMaestro.SizeSpec
MakieMaestro.RelativeSize
MakieMaestro.FigHeight
MakieMaestro._savefig
MakieMaestro._savepdftex
```
Expand All @@ -56,6 +64,7 @@ MakieMaestro.Themes.hwratio!
MakieMaestro.Themes.update_theme
MakieMaestro.Themes.update_theme!
MakieMaestro.Themes.get_theme
MakieMaestro.Themes.theme_keys
```

```@raw html
Expand Down
10 changes: 10 additions & 0 deletions docs/src/workflows/pluto.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,13 @@ This makes the initial run in a resumed session a lot faster.
!!! note "How does it work?"
There is a global dictionary that stores the figures and the figure is shown only if the dictionary already contains
this figure.

!!! tip "Edit notebook code in your editor"
If you would like to have the notebook code watch the content of the notebook file so that you can directly edit
that file and see the outcome, this is possible in __Pluto.jl__ by specifying the `Pluto.ServerSession` prior to
launching it like so:
```julia
session = Pluto.ServerSession()
session.options.server.auto_reload_from_file = true
Pluto.run(session)
```
87 changes: 82 additions & 5 deletions docs/src/workflows/savefig.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
CurrentModule = MakieMaestro
```

# Exporting figures publication
# Exporting publication figures

You often want to apply specific themes or export figures in different sizes.
For instance a margin figure size and a full `\textwidth` size.
Expand Down Expand Up @@ -88,28 +88,36 @@ When you are satisfied with the figure function, as you can check interactively,

```@example bessel-y-plot
figure_dir!(".") # hide
savefig(bessely_fig; formats = Set([MakieMaestro.Svg])) # bessely_fig.svg
savefig(bessely_fig, ["svg"]) # bessely_fig.svg
nothing # hide
```
![](bessely_fig.svg)

If this figure is intended for the appendix, we can theme it with
```@example bessel-y-plot
savefig(bessely_fig, "bessely_fig_appendix"; override_theme = Themes.get_theme(:appendix), formats = Set([MakieMaestro.Svg])) # bessely_fig_appendix.svg
savefig(bessely_fig, "bessely_fig_appendix.svg"; override_theme = Themes.get_theme(:appendix)) # bessely_fig_appendix.svg
```
![](bessely_fig_appendix.svg)


!!! tip "Export Format"
In many cases we would always want to export the figure in the same format. In this case for a web page (this
documentation), we would want `.svg`. To make this easier, you can define the default export format using
```@example bessel-y-plot
export_format!(:svg)
```

To make is larger for (maybe for a full page figure), we can do that with

```@example bessel-y-plot
savefig(bessely_fig, "bessely_fig_large", Themes.A4_WIDTH; override_theme = Themes.get_theme(:appendix), formats = Set([MakieMaestro.Svg])) # bessely_fig_large.svg
savefig(bessely_fig, "bessely_fig_large", Themes.A4_WIDTH; override_theme = Themes.get_theme(:appendix)) # bessely_fig_large.svg
```
![](bessely_fig_large.svg)

Changing the aspect ratio is possible by supplying the `hwratio` argument

```@example bessel-y-plot
savefig(bessely_fig, "bessely_fig_wide", Themes.A4_WIDTH, 0.4; override_theme = Themes.get_theme(:appendix), formats = Set([MakieMaestro.Svg])) # bessely_fig_wide.svg
savefig(bessely_fig, "bessely_fig_wide", Themes.A4_WIDTH, 0.4; override_theme = Themes.get_theme(:appendix)) # bessely_fig_wide.svg
```
![](bessely_fig_wide.svg)

Expand All @@ -121,3 +129,72 @@ savefig(bessely_fig, "bessely_fig_wide", Themes.A4_WIDTH, 0.4; override_theme =
<img src="workflows/bessely_fig_appendix.svg" alt="Bessel Y figure themed for the appendix" style="margin-left: 10px;">
</div>
```

# Arguments to the `savefig` function
The intension of this exporting functionality is such that you do not need to think much about the process of saving the
output of your research. After some initializations of regarding the setting up of your sizing ([`width!`](@ref
MakieMaestro.Themes.width!), [`hwratio!`](@ref MakieMaestro.Themes.hwratio!)), desired format [`export_format!`](@ref
MakieMaestro.export_format!) and directory to store the figures in ([`figure_dir!`](@ref MakieMaestro.figure_dir!)), you
should be set and as long as you structure the visualizations into functions, keeping exported figures should be as
simple as calling [`savefig`](@ref) with any set of reasonable arguments which indicate your needs about the figure.

In this nature, [`savefig`](@ref) may be called with a great number of variants of arguments. The only necessary
knowledge is the order in which the aspects of the figure are passed to the function. This order is as follows:
1. _Source of the figure_ -- What you want to export?
2. _File specification_ -- Where? In which format? and What name? to export to.
3. _Size specification_ -- What are the dimensions of the figure (determined by its intended use in a
poster/report/slides/article etc.)
All of these may be specified using various arguments or left to the default. For a clearer understanding of what
arguments are acceptable see [`savefig`](@ref) ([`SizeSpec`](@ref MakieMaestro.SizeSpec), [`PathSpec`](@ref
MakieMaestro.PathSpec), [`FunctionSpec`](@ref MakieMaestro.FunctionSpec)).
Here are some examples of possible calls who's outcome is mostly self explanatory.

Setup of the default values
```@repl argument-cascade
using MakieMaestro # hide
using MakieMaestro.Themes
figure_dir!(".")
width!(Themes.A4_WIDTH)
export_format!(:svg)
```
and figures can then be exported using various argument sets
```@example argument-cascade
using MakieMaestro: MakieMaestro as MM
function lissajous_knot(a=3, b=4, δ=3π/4; A=1, B=1, N=1000)
ts = range(0,2π,N)
xs = @. A*sin(a*ts + δ)
ys = @. B*sin(b*ts)
return lines(xs, ys)
end
savefig(lissajous_knot) # lissajous_knot.svg
rm("lissajous_knot.svg") # hide
savefig(lissajous_knot, (8, 3)) # lissajous_knot.svg with a=8 and b=3
rm("lissajous_knot.svg") # hide
savefig(lissajous_knot, (6, 8); A=3) # lissajous_knot.svg with a=6, b=8 and A=3
rm("lissajous_knot.svg") # hide
savefig(lissajous_knot, [:svg, "pdf", MM.Png]) # lissajous_knot.{svg, pdf, png} in multiple formats
rm.("lissajous_knot.$e" for e in ["pdf", "svg", "png"]) # hide
savefig(lissajous_knot, "not_a_knot") # not_a_knot.svg
rm("not_a_knot.svg") # hide
savefig(lissajous_knot, "not_a_knot.pdf") # not_a_knot.pdf
rm("not_a_knot.pdf") # hide
savefig(lissajous_knot, "not_a_knot.{png,eps} ") # not_a_knot.{png, eps} in multiple formats
rm.("not_a_knot.$e" for e in ["png", "eps"]) # hide
savefig(lissajous_knot, (2,1)) # lissajous_knot.svg 2×default width
rm("lissajous_knot.svg") # hide
savefig(lissajous_knot, 2, 1) # lissajous_knot.svg 2×default width and hwratio=1
rm("lissajous_knot.svg") # hide
savefig(lissajous_knot, 10u"cm", 1) # lissajous_knot.svg 10 cm wide and square aspect ratio
rm("lissajous_knot.svg") # hide
# NOTE: Since the size tuple may be confused as the arguments to the figure function, we need to construct `FunctionSpec` explicitely
savefig(MM.FunctionSpec(lissajous_knot), (10u"cm", 20u"cm")) # lissajous_knot.svg 10 cm wide and 20 cm high
rm("lissajous_knot.svg") # hide
isdir("./alt_dir") || mkdir("./alt_dir") # hide
savefig(lissajous_knot, "alt_dir/lissajous_knot.svg") # lissajous_knot.svg in alt_dir
rm("./alt_dir/lissajous_knot.svg") # hide
savefig(lissajous_knot, ["pdf"], "alt_dir") # lissajous_knot.pdf in alt_dir
rm("./alt_dir/lissajous_knot.pdf") # hide
rm("./alt_dir/", recursive=true) # hide
```
14 changes: 2 additions & 12 deletions src/MakieMaestro.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,25 +28,15 @@ module Units
@unit pt "pt" Point (1//72)u"inch" false
end

# TODO: Update the theme to be generated depending on the ***_DEFAULT as it cannot be set beforehand <17-10-24>

# TODO: Add the Pluto snippet that I use for the backend function <16-10-24>
# FIX: Define WIDTH_DEFAULT and HWRATIO_DEFAULT <15-10-24>
# FIX: The cache location should be parametrized <15-10-24>
# TODO: Add the `L` function <15-10-24>

include("themes/theme.jl")
include("save-fig.jl")
include("theme/theme.jl")
include("export/savefig.jl")
include("shortcuts.jl")
include("recipe-modifications.jl")
include("pluto-helpers.jl")

function __init__()
Unitful.register(Units)

# TODO: Similarly to this the default for saving figures when in a documenter context should be `SVG` instead of
# `PDF`. The context of the run should be determined here and used in the `savefig` in some method that defines the
# default formats to generate. <09-01-25>
if @isdefined PlutoRunner # running inside Pluto
WGLMakie.activate!()
elseif isinteractive() # running in REPL
Expand Down
Loading

2 comments on commit df6d34d

@kunzaatko
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator register
Release notes:

[0.2.0] - 2025-01-31

🚀 Features

  • (docs) Add DocumenterInterLinks for cross-documentation references by @kunzaatko

  • Add coverage badge to README by @kunzaatko

  • (formats) Add format parsing and default format management by @kunzaatko

  • (export) [breaking] Improve struct documentation and display methods by @kunzaatko

🐛 Bug Fixes

  • (docs) Improve savefig documentation and cross-references by @kunzaatko

  • (export) [breaking] Improve error handling for argument confusion by @kunzaatko

  • (export) Improve error handling and documentation by @kunzaatko

🚜 Refactor

  • (export) [breaking] Reorganize figure saving functionality by @kunzaatko

  • [breaking] Rename HeightLength to FigHeight and export_formats to export_format by @kunzaatko

  • (export) [breaking] Simplify format handling and improve API by @kunzaatko

📚 Documentation

  • (save-fig) Add documentation for internal save functions by @kunzaatko

  • (savefig) Add detailed argument documentation and examples by @kunzaatko

🧪 Testing

  • Skip PDF path test in GitHub Actions CI by @kunzaatko

⚙️ Miscellaneous Tasks

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/124102

Tagging

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.2.0 -m "<description of version>" df6d34d64ccb4d60f90a163a5f1467f7d69b40bf
git push origin v0.2.0

Please sign in to comment.