Skip to content

Commit 20abb06

Browse files
committed
Improved rigor for marker_z and line_z
1 parent e5479f4 commit 20abb06

File tree

2 files changed

+73
-33
lines changed

2 files changed

+73
-33
lines changed

ext/UnitfulExt.jl

Lines changed: 53 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Main recipe
2222
if axisletter === :z && get(plotattributes, :seriestype, :nothing) clims_types
2323
u = get(plotattributes, :zunit, _unit(eltype(x)))
2424
ustripattribute!(plotattributes, :clims, u)
25-
append_unit_if_needed!(plotattributes, :colorbar_title, u)
25+
append_cbar_unit_if_needed!(plotattributes, u)
2626
end
2727
fixaxis!(plotattributes, x, axisletter)
2828
end
@@ -34,7 +34,7 @@ function fixaxis!(attr, x, axisletter)
3434
axis = Symbol(axisletter, :axis) # xaxis, yaxis, zaxis
3535
# if the subplot already exists with data, use that unit
3636
sp = get(attr, :subplot, 1)
37-
if sp length(attr[:plot_object])
37+
if sp length(attr[:plot_object]) && attr[:plot_object].n > 0
3838
spu = getaxisunit(attr[:plot_object][sp][axis])
3939
if !isnothing(spu)
4040
u = spu
@@ -51,9 +51,9 @@ function fixaxis!(attr, x, axisletter)
5151
ustripattribute!(attr, :fillrange, u)
5252
end
5353
fixaspectratio!(attr, u, axisletter)
54-
fixmarkercolor!(attr)
54+
fixseriescolor!(attr, :marker_z)
55+
fixseriescolor!(attr, :line_z)
5556
fixmarkersize!(attr)
56-
fixlinecolor!(attr)
5757
_ustrip.(u, x) # strip the unit
5858
end
5959

@@ -62,7 +62,7 @@ end
6262
u = get(plotattributes, :zunit, _unit(eltype(z)))
6363
ustripattribute!(plotattributes, :clims, u)
6464
z = fixaxis!(plotattributes, z, :z)
65-
append_unit_if_needed!(plotattributes, :colorbar_title, u)
65+
append_cbar_unit_if_needed!(plotattributes, u)
6666
x, y, z
6767
end
6868

@@ -154,15 +154,30 @@ function fixaspectratio!(attr, u, axisletter)
154154
end
155155
156156
# Markers / lines
157-
function fixmarkercolor!(attr)
158-
u = ustripattribute!(attr, :marker_z)
159-
ustripattribute!(attr, :clims, u)
160-
u == NoUnits || append_unit_if_needed!(attr, :colorbar_title, u)
161-
end
162-
function fixlinecolor!(attr)
163-
u = ustripattribute!(attr, :line_z)
157+
function fixseriescolor!(attr, key)
158+
sp = get(attr, :subplot, 1)
159+
# Precedence to user-passed zunit
160+
if haskey(attr, :zunit)
161+
u = attr[:zunit]
162+
ustripattribute!(attr, key, u)
163+
# Then to an existing subplot's colorbar title
164+
elseif sp length(attr[:plot_object]) && attr[:plot_object].n > 0
165+
cbar_title = get(attr[:plot_object][sp], :colorbar_title, nothing)
166+
spu = (cbar_title isa UnitfulString ? cbar_title.unit : nothing)
167+
if !isnothing(spu)
168+
u = spu
169+
ustripattribute!(attr, key, u)
170+
else
171+
u = ustripattribute!(attr, key)
172+
end
173+
# Otherwise, get from the attribute
174+
else
175+
u = ustripattribute!(attr, key)
176+
end
164177
ustripattribute!(attr, :clims, u)
165-
u == NoUnits || append_unit_if_needed!(attr, :colorbar_title, u)
178+
# fixseriescolor! is called for each axis, so after the first pass,
179+
# u will be NoUnits and we don't want to append unit again
180+
u == NoUnits || append_cbar_unit_if_needed!(attr, u)
166181
end
167182
fixmarkersize!(attr) = ustripattribute!(attr, :markersize)
168183

@@ -192,6 +207,8 @@ end
192207

193208
#=======================================
194209
Label string containing unit information
210+
Used only for colorbars, etc., which don't
211+
have a bettter place for storing units
195212
=======================================#
196213

197214
const APS = Plots.AbstractProtectedString
@@ -202,42 +219,45 @@ end
202219

203220
#=====================================
204221
Append unit to labels when appropriate
205-
This is needed for colorbars, mostly,
206-
since axes have their own handling
222+
This is needed for colorbars, etc., since axes have
223+
distinct unit handling
207224
=====================================#
208225

209-
append_unit_if_needed!(attr, key, u) =
210-
append_unit_if_needed!(attr, key, get(attr, key, nothing), u)
226+
append_cbar_unit_if_needed!(attr, u) =
227+
append_cbar_unit_if_needed!(attr, get(attr, :colorbar_title, nothing), u)
211228
# dispatch on the type of `label`
212-
append_unit_if_needed!(attr, key, label::Plots.ProtectedString, u) = nothing
213-
append_unit_if_needed!(attr, key, label::UnitfulString, u) = nothing
214-
function append_unit_if_needed!(attr, key, label::Nothing, u)
215-
attr[key] = if attr[:plot_object].backend == Plots.PGFPlotsXBackend()
229+
append_cbar_unit_if_needed!(attr, label::UnitfulString, u) = nothing
230+
function append_cbar_unit_if_needed!(attr, label::Nothing, u)
231+
unitformat = get(attr, Symbol(:z, :unitformat), :round)
232+
if unitformat [:nounit, :none, false, nothing]
233+
return attr[:colorbar_title] = UnitfulString("", u)
234+
end
235+
attr[:colorbar_title] = if Plots.backend_name() === :pgfplotsx
216236
UnitfulString(LaTeXString(latexify(u)), u)
217237
else
218238
UnitfulString(string(u), u)
219239
end
220240
end
221-
function append_unit_if_needed!(attr, key, label::S, u) where {S<:AbstractString}
222-
isempty(label) && return attr[key] = UnitfulString(label, u)
223-
if attr[:plot_object].backend == Plots.PGFPlotsXBackend()
224-
attr[key] = UnitfulString(
241+
function append_cbar_unit_if_needed!(attr, label::S, u) where {S<:AbstractString}
242+
isempty(label) && return attr[:colorbar_title] = UnitfulString(label, u)
243+
attr[:colorbar_title] = if Plots.backend_name() :pgfplotsx
244+
UnitfulString(
225245
LaTeXString(
226246
Plots.format_unit_label(
227247
label,
228248
latexify(u),
229-
get(attr, Symbol(get(attr, :letter, ""), :unitformat), :round),
249+
get(attr, :zunitformat, :round),
230250
),
231251
),
232252
u,
233253
)
234254
else
235-
attr[key] = UnitfulString(
255+
UnitfulString(
236256
S(
237257
Plots.format_unit_label(
238258
label,
239259
u,
240-
get(attr, Symbol(get(attr, :letter, ""), :unitformat), :round),
260+
get(attr, :zunitformat, :round),
241261
),
242262
),
243263
u,
@@ -246,9 +266,8 @@ function append_unit_if_needed!(attr, key, label::S, u) where {S<:AbstractString
246266
end
247267

248268
getaxisunit(::Nothing) = nothing
249-
getaxisunit(s::UnitfulString) = s.unit
250-
getaxisunit(a::Axis) = getaxisunit(a[:unit])
251269
getaxisunit(u) = u
270+
getaxisunit(a::Axis) = getaxisunit(a[:unit])
252271

253272
#==============
254273
Fix annotations
@@ -280,8 +299,10 @@ function Plots.locate_annotation(
280299
rel::NTuple{N,<:MissingOrQuantity},
281300
label,
282301
) where {N}
283-
units = getaxisunit(sp.attr[:xaxis], sp.attr[:yaxis], sp.attr[:zaxis])
284-
Plots.locate_annotation(sp, _ustrip.(zip(units, rel)), label)
302+
units = getaxisunit(sp.attr[:xaxis]),
303+
getaxisunit(sp.attr[:yaxis]),
304+
getaxisunit(sp.attr[:zaxis])
305+
PlotsBase.locate_annotation(sp, _ustrip.(zip(units, rel)), label)
285306
end
286307

287308
#==================#

test/test_unitful.jl

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ using Unitful: m, cm, s, DimensionError
55
xguide(pl, idx = length(pl.subplots)) = Plots.get_guide(pl.subplots[idx].attr[:xaxis])
66
yguide(pl, idx = length(pl.subplots)) = Plots.get_guide(pl.subplots[idx].attr[:yaxis])
77
zguide(pl, idx = length(pl.subplots)) = Plots.get_guide(pl.subplots[idx].attr[:zaxis])
8+
ctitle(pl, idx = length(pl.subplots)) = pl.subplots[idx].attr[:colorbar_title]
89
xseries(pl, idx = length(pl.series_list)) = pl.series_list[idx].plotattributes[:x]
910
yseries(pl, idx = length(pl.series_list)) = pl.series_list[idx].plotattributes[:y]
1011
zseries(pl, idx = length(pl.series_list)) = pl.series_list[idx].plotattributes[:z]
@@ -269,7 +270,13 @@ end
269270
x, y = rand(10) * us[1], rand(10) * us[2]
270271
@test scatter(x, y) isa Plots.Plot
271272
@test scatter(x, y, markersize = x) isa Plots.Plot
272-
@test scatter(x, y, line_z = x) isa Plots.Plot
273+
274+
@test scatter(x, y, marker_z = x) isa Plots.Plot
275+
if us[1] != us[2] && us[1] != 1 && us[2] != 1 # Non-matching dimensions
276+
@test_throws DimensionError scatter!(x, y, marker_z = y)
277+
else # One is dimensionless, or have same dimensions
278+
@test scatter!(x, y, marker_z = y) isa PlotsBase.Plot #
279+
end
273280
end
274281

275282
@testset "contour(x::$(us[1]), y::$(us[2]))" for us in collect(
@@ -286,6 +293,18 @@ end
286293
@test plot(y, label = P"meters") isa Plots.Plot
287294
end
288295
296+
@testset "colorbar title" begin
297+
298+
x, y = (1:0.01:2) * m, (1:0.02:2) * s
299+
z = x' ./ y
300+
pl = contour(x, y, z)
301+
@test ctitle(pl) ["m s^-1", "m s⁻¹"]
302+
pl = contourf(x, y, z, zunit = u"km/hr")
303+
@test ctitle(pl) ["km hr^-1", "km hr⁻¹"]
304+
pl = heatmap(x, y, z, zunit = u"cm/s", zunitformat = :square, colorbar_title = "v")
305+
@test ctitle(pl) ["v [cm s^-1]", "v [cm s⁻¹]"]
306+
end
307+
289308
@testset "twinx (#4750)" begin
290309
y = rand(10) * u"m"
291310
pl = plot(y; xlabel = "check", ylabel = "hello")

0 commit comments

Comments
 (0)