Skip to content

Commit 33152e9

Browse files
authored
Merge pull request #77 from gustaphe/aspectratio
Unitful aspect ratios
2 parents 7741be7 + 79b7ada commit 33152e9

File tree

5 files changed

+86
-1
lines changed

5 files changed

+86
-1
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,5 @@ docs/Manifest.toml
1111
docs/build/
1212
docs/src/examples/
1313
docs/src/notebooks/
14+
15+
test/test.png

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "UnitfulRecipes"
22
uuid = "42071c24-d89e-48dd-8a24-8a12d9b8861f"
33
authors = ["Benoit Pasquier", "Jan Weidner"]
4-
version = "1.5.3"
4+
version = "1.6.0"
55

66
[deps]
77
RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"

docs/lit/examples/1_Examples.jl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,3 +188,24 @@ plot!(model, u"s"; label="True function")
188188

189189
plot(u"m", u"s")
190190
plot!([2u"ft"], [1u"minute"], st=:scatter)
191+
192+
# ## Aspect ratio
193+
#
194+
# Unlike in a normal unitless plot, the aspect ratio of a unitful plot is in turn a unitful
195+
# number $r$, such that $r\cdot \hat{y}$ would take as much space on the $x$ axis as
196+
# $\hat{y}$ does on the $y$ axis.
197+
#
198+
# By default, `aspect_ratio` is set to `:auto`, which lets you ignore this.
199+
#
200+
# Another special value is `:equal`, which (possibly unintuitively) corresponds to $r=1$.
201+
# Consider a rectangle drawn in a plot with $\mathrm{m}$ on the $x$ axis and
202+
# $\mathrm{km}$ on the $y$ axis. If the rectangle is
203+
# $100\;\mathrm{m} \times 0.1\;\mathrm{km}$, `aspect_ratio=:equal` will make it appear
204+
# square.
205+
206+
plot(
207+
plot(randn(10)u"m", randn(10)u"dm"; aspect_ratio=:equal, title=":equal"),
208+
plot(randn(10)u"m", randn(10)u"s"; aspect_ratio=2u"m/s",
209+
title="\$2\\;\\mathrm{m}/\\mathrm{s}\$"),
210+
plot(randn(10)u"m", randn(10); aspect_ratio=5u"m", title="\$5\\;\\mathrm{m}\$")
211+
)

src/UnitfulRecipes.jl

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ function fixaxis!(attr, x, axisletter)
5050
ustripattribute!(attr, :ribbon, u)
5151
ustripattribute!(attr, :fillrange, u)
5252
end
53+
fixaspectratio!(attr, u, axisletter)
5354
fixmarkercolor!(attr)
5455
fixmarkersize!(attr)
5556
fixlinecolor!(attr)
@@ -124,6 +125,36 @@ end
124125
#===============
125126
Attribute fixing
126127
===============#
128+
# Aspect ratio
129+
function fixaspectratio!(attr, u, axisletter)
130+
aspect_ratio = get!(attr, :aspect_ratio, :auto)
131+
if aspect_ratio in (:auto, :none)
132+
# Keep the default behavior (let Plots figure it out)
133+
return
134+
end
135+
if aspect_ratio === :equal
136+
aspect_ratio = 1
137+
end
138+
#=======================================================================================
139+
Implementation example:
140+
141+
Consider an x axis in `u"m"` and a y axis in `u"s"`, and an `aspect_ratio` in `u"m/s"`.
142+
On the first pass, `axisletter` is `:x`, so `aspect_ratio` is converted to `u"m/s"/u"m"
143+
= u"s^-1"`. On the second pass, `axisletter` is `:y`, so `aspect_ratio` becomes
144+
`u"s^-1"*u"s" = 1`. If at this point `aspect_ratio` is *not* unitless, an error has been
145+
made, and the default aspect ratio fixing of Plots throws a `DimensionError` as it tries
146+
to compare `0 < 1u"m"`.
147+
=======================================================================================#
148+
if axisletter === :y
149+
attr[:aspect_ratio] = aspect_ratio*u
150+
return
151+
end
152+
if axisletter === :x
153+
attr[:aspect_ratio] = aspect_ratio/u
154+
return
155+
end
156+
return
157+
end
127158

128159
# Markers / lines
129160
function fixmarkercolor!(attr)

test/runtests.jl

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ using Test, Unitful, Plots
22
using Unitful: m, s, cm, DimensionError
33
using UnitfulRecipes
44

5+
testfile = "test.png"
6+
57
# Some helper functions to access the subplot labels and the series inside each test plot
68
xguide(plt, idx=length(plt.subplots)) = plt.subplots[idx].attr[:xaxis].plotattributes[:guide]
79
yguide(plt, idx=length(plt.subplots)) = plt.subplots[idx].attr[:yaxis].plotattributes[:guide]
@@ -293,6 +295,35 @@ end
293295
@test yguide(plt) == "s"
294296
end
295297

298+
@testset "Aspect ratio" begin
299+
plt = plot(
300+
(1:10)u"m",
301+
(1:10)u"dm";
302+
aspect_ratio=:equal,
303+
)
304+
savefig(plt, testfile) # Force a render, to make it evaluate aspect ratio
305+
@test abs(-(ylims(plt)...)) > 50
306+
plt = plot(
307+
(1:10)u"m",
308+
(1:10)u"dm";
309+
aspect_ratio=2,
310+
)
311+
savefig(plt, testfile)
312+
@test 25 < abs(-(ylims(plt)...)) < 50
313+
plt = plot(
314+
(1:10)u"m",
315+
(1:10)u"s";
316+
aspect_ratio=1u"m/s",
317+
)
318+
savefig(plt, testfile)
319+
@test 7.5 < abs(-(ylims(plt)...)) < 12.5
320+
@test_throws DimensionError savefig(plot(
321+
(1:10)u"m",
322+
(1:10)u"s";
323+
aspect_ratio=:equal,
324+
), testfile)
325+
end
326+
296327
# https://github.com/jw3126/UnitfulRecipes.jl/issues/60
297328
@testset "Start with empty plot" begin
298329
plt = plot()

0 commit comments

Comments
 (0)