Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix UnitfulExt for PGFPlotsX take 2 #4747

Merged
merged 11 commits into from
May 17, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
branches: [master]
pull_request:

concurrency:
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

Expand All @@ -28,19 +28,19 @@ jobs:
fail-fast: false
matrix:
version:
- '1.6' # LTS (minimal declared julia compat in `Project.toml`)
- '1.8' # latest stable
- '1.9' # (minimal declared julia compat in `Project.toml`)
# - '1.8' # latest stable
os: [ubuntu-latest, windows-latest, macos-latest]
arch: [x64]
include:
- os: ubuntu-latest
prefix: xvfb-run # julia-actions/julia-runtest/blob/master/README.md
- os: ubuntu-latest
prefix: xvfb-run
version: '1.7' # only test intermediate release on `ubuntu` to spare resources
- os: ubuntu-latest
prefix: xvfb-run
version: '~1.9.0-0' # upcoming julia version, next `rc`
# - os: ubuntu-latest
# prefix: xvfb-run
# version: '1.7' # only test intermediate release on `ubuntu` to spare resources
# - os: ubuntu-latest
# prefix: xvfb-run
# version: '~1.9.0-0' # upcoming julia version, next `rc`
- os: ubuntu-latest
prefix: xvfb-run
version: 'nightly'
Expand Down
36 changes: 19 additions & 17 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ NaNMath = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3"
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
PlotThemes = "ccf2f8ad-2431-5c83-bf29-c5338b663b6a"
PlotUtils = "995b91a9-d308-5afd-9ec6-746e21dbc043"
PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a"
Preferences = "21216c6a-2e73-6563-6e65-726566657250"
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"
Expand All @@ -32,14 +33,28 @@ RelocatableFolders = "05181044-ff0b-4ac5-8273-598c1e38db00"
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
Scratch = "6c6a2e73-6563-6170-7368-637461726353"
Showoff = "992d4aef-0814-514b-bc4d-f2e9a6c4116f"
PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
UnicodeFun = "1cfade01-22cf-5700-b092-accc4b62d6e1"
UnitfulLatexify = "45397f5d-5981-4c77-b2b3-fc36d6e9b728"
Unzip = "41fe7b60-77ed-43a1-b4f0-825fd5a5650d"

[weakdeps]
FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549"
GeometryBasics = "5c1252a2-5f33-56bf-86c9-59e7332b4326"
IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a"
ImageInTerminal = "d8c32880-2388-543b-8c61-d9f865259254"
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"

[extensions]
FileIOExt = "FileIO"
GeometryBasicsExt = "GeometryBasics"
IJuliaExt = "IJulia"
ImageInTerminalExt = "ImageInTerminal"
UnitfulExt = "Unitful"

[compat]
Contour = "0.5 - 0.6"
FFMPEG = "0.2 - 0.4"
Expand All @@ -61,6 +76,7 @@ PlotUtils = "1"
PlotlyBase = "0.7 - 0.8"
PlotlyJS = "0.18"
PlotlyKaleido = "1"
PrecompileTools = "1"
Preferences = "1"
PyPlot = "2"
PythonPlot = "1"
Expand All @@ -71,19 +87,12 @@ RelocatableFolders = "0.3, 1"
Requires = "1"
Scratch = "1"
Showoff = "0.3.1, 1"
PrecompileTools = "1"
StatsBase = "0.33"
UnicodeFun = "0.4"
UnicodePlots = "3.4"
UnitfulLatexify = "1"
Unzip = "0.1 - 0.2"
julia = "1.6"

[extensions]
FileIOExt = "FileIO"
GeometryBasicsExt = "GeometryBasics"
IJuliaExt = "IJulia"
ImageInTerminalExt = "ImageInTerminal"
UnitfulExt = "Unitful"
julia = "1.9"
BeastyBlacksmith marked this conversation as resolved.
Show resolved Hide resolved

[extras]
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
Expand Down Expand Up @@ -121,10 +130,3 @@ VisualRegressionTests = "34922c18-7c2a-561c-bac1-01e79b2c4c92"

[targets]
test = ["Aqua", "Colors", "Distributions", "FileIO", "FilePathsBase", "FreeType", "Gaston", "GeometryBasics", "Gtk", "ImageMagick", "Images", "InspectDR", "LibGit2", "OffsetArrays", "PGFPlotsX", "PlotlyJS", "PlotlyBase", "PyPlot", "PythonPlot", "PlotlyKaleido", "HDF5", "RDatasets", "SentinelArrays", "StableRNGs", "StaticArrays", "StatsPlots", "Test", "TestImages", "UnicodePlots", "Unitful", "VisualRegressionTests"]

[weakdeps]
FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549"
GeometryBasics = "5c1252a2-5f33-56bf-86c9-59e7332b4326"
IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a"
ImageInTerminal = "d8c32880-2388-543b-8c61-d9f865259254"
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"
51 changes: 36 additions & 15 deletions ext/UnitfulExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ module UnitfulExt
import Plots: Plots, @ext_imp_use, @recipe, PlotText, Subplot, AVec, AMat, Axis
import RecipesBase
@ext_imp_use :import Unitful Quantity unit ustrip Unitful dimension Units NoUnits LogScaled logunit MixedUnits Level Gain uconvert
@ext_imp_use :import LaTeXStrings LaTeXString
@ext_imp_use :import Latexify latexify
@ext_imp_use :using UnitfulLatexify

const MissingOrQuantity = Union{Missing,<:Quantity,<:LogScaled}

Expand Down Expand Up @@ -214,12 +217,38 @@ append_unit_if_needed!(attr, key, u) =
# dispatch on the type of `label`
append_unit_if_needed!(attr, key, label::ProtectedString, u) = nothing
append_unit_if_needed!(attr, key, label::UnitfulString, u) = nothing
append_unit_if_needed!(attr, key, label::Nothing, u) =
(attr[key] = UnitfulString(string(u), u))
function append_unit_if_needed!(attr, key, label::Nothing, u)
attr[key] = if attr[:plot_object].backend == Plots.PGFPlotsXBackend()
UnitfulString(LaTeXString(latexify(u)), u)
else
UnitfulString(string(u), u)
end
end
function append_unit_if_needed!(attr, key, label::S, u) where {S<:AbstractString}
isempty(label) && return attr[key] = UnitfulString(label, u)
attr[key] =
UnitfulString(S(format_unit_label(label, u, get(attr, :unitformat, :round))), u)
if attr[:plot_object].backend == Plots.PGFPlotsXBackend()
attr[key] = UnitfulString(
LaTeXString(
format_unit_label(
label,
latexify(u),
get(attr, Symbol(attr[:letter], :unitformat), :round),
),
),
u,
)
else
attr[key] = UnitfulString(
S(
format_unit_label(
label,
u,
get(attr, Symbol(attr[:letter], :unitformat), :round),
),
),
u,
)
end
end

#=============================================
Expand All @@ -237,6 +266,7 @@ const UNIT_FORMATS = Dict(
:slashcurly => (" / {", "}"),
:slashangle => (" / <", ">"),
:verbose => " in units of ",
:none => nothing,
)

format_unit_label(l, u, f::Nothing) = string(l, ' ', u)
Expand Down Expand Up @@ -293,17 +323,8 @@ function _unit(x)
unit(x)
end

Plots.pgfx_sanitize_string(s::UnitfulString) = begin
tex_str = if (str_unit = string(s.unit)) == s.content
""
else
Plots.pgfx_sanitize_string(s.content)
end
tex_unit = replace(Plots.wrap_power_label(str_unit), ' ' => '~')
if !Plots.pgfx_is_inline_math(tex_unit)
tex_unit = "\\($tex_unit\\)" # force inline math mode
end
isempty(tex_str) ? tex_unit : tex_str * ' ' * tex_unit
function Plots.pgfx_sanitize_string(s::UnitfulString)
UnitfulString(Plots.pgfx_sanitize_string(s.content), s.unit)
end

end # module
3 changes: 2 additions & 1 deletion src/arg_desc.jl
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,10 @@ const _arg_desc = KW(
:showaxis => (Union{Bool,Symbol,AStr}, "Show the axis. `true`, `false`, `:show`, `:hide`, `:yes`, `:no`, `:x`, `:y`, `:z`, `:xy`, ..., `:all`, `:off`."),
:widen => (Union{Bool,Real,Symbol}, """
Widen the axis limits by a small factor to avoid cut-off markers and lines at the borders.
If set to `true`, scale the axis limits by the default factor of $(default_widen_factor).
If set to `true`, scale the axis limits by the default factor of $(default_widen_factor).
A different factor may be specified by setting `widen` to a number.
Defaults to `:auto`, which widens by the default factor unless limits were manually set.
See also the `scale_limits!` function for scaling axis limits in an existing plot."""),
:draw_arrow => (Bool, "Draw arrow at the end of the axis."),
:unitformat => (Union{Bool,Nothing,Symbol,Char,String,NTuple{<:Union{Char,String}},Function}, """Check examples in https://docs.juliaplots.org/stable/generated/unitfulext_examples/#Unit-formatting"""),
)
1 change: 1 addition & 0 deletions src/args.jl
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,7 @@ const _axis_defaults = KW(
:showaxis => true,
:widen => :auto,
:draw_arrow => false,
:unitformat => :round,
)

const _suppress_warnings = Set{Symbol}([
Expand Down
28 changes: 15 additions & 13 deletions src/backends/pgfplotsx.jl
Original file line number Diff line number Diff line change
Expand Up @@ -766,26 +766,28 @@ end

function pgfx_get_legend_style(sp)
cstr = plot_color(sp[:legend_background_color])
Options(
return merge(
pgfx_linestyle(
pgfx_thickness_scaling(sp),
sp[:legend_foreground_color],
alpha(plot_color(sp[:legend_foreground_color])),
"solid",
) => nothing,
"fill" => cstr,
"fill opacity" => alpha(cstr),
"text opacity" => alpha(plot_color(sp[:legend_font_color])),
"font" => pgfx_font(sp[:legend_font_pointsize], pgfx_thickness_scaling(sp)),
"text" => plot_color(sp[:legend_font_color]),
"cells" => Options(
"anchor" => get(
(left = "west", right = "east", hcenter = "center"),
legendfont(sp).halign,
"west",
),
Options(
"fill" => cstr,
"fill opacity" => alpha(cstr),
"text opacity" => alpha(plot_color(sp[:legend_font_color])),
"font" => pgfx_font(sp[:legend_font_pointsize], pgfx_thickness_scaling(sp)),
"text" => plot_color(sp[:legend_font_color]),
"cells" => Options(
"anchor" => get(
(left = "west", right = "east", hcenter = "center"),
legendfont(sp).halign,
"west",
),
),
pgfx_get_legend_pos(sp[:legend_position])...,
),
BeastyBlacksmith marked this conversation as resolved.
Show resolved Hide resolved
pgfx_get_legend_pos(sp[:legend_position])...,
)
end

Expand Down
31 changes: 22 additions & 9 deletions test/test_pgfplotsx.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using Test, Plots, Unitful, LaTeXStrings

function create_plot(args...; kwargs...)
pl = plot(args...; kwargs...)
return pl, repr("application/x-tex", pl)
Expand Down Expand Up @@ -119,7 +121,7 @@ with(:pgfplotsx) do
bg = :linen,
xlim = (0, 10),
ylim = (0, 10),
) isa Plot
) isa Plots.Plot
end

@testset "Layout" begin
Expand All @@ -128,13 +130,13 @@ with(:pgfplotsx) do
layout = 4,
palette = [:grays :blues :hot :rainbow],
bg_inside = [:orange :pink :darkblue :black],
) isa Plot
) isa Plots.Plot
end

@testset "Polar plots" begin
Θ = range(0, stop = 1.5π, length = 100)
r = abs.(0.1 * randn(100) + sin.(3Θ))
@test plot(Θ, r, proj = :polar, m = 2) isa Plot
@test plot(Θ, r, proj = :polar, m = 2) isa Plots.Plot
end

@testset "Drawing shapes" begin
Expand Down Expand Up @@ -170,11 +172,11 @@ with(:pgfplotsx) do
xlim = (0, 1),
ylim = (0, 1),
leg = false,
) isa Plot
) isa Plots.Plot
end

@testset "Histogram 2D" begin
@test histogram2d(randn(10_000), randn(10_000), nbins = 20) isa Plot
@test histogram2d(randn(10_000), randn(10_000), nbins = 20) isa Plots.Plot
end

@testset "Heatmap-like" begin
Expand All @@ -188,7 +190,7 @@ with(:pgfplotsx) do
@test axis["colormap name"] == "plots1"
end

@test wireframe(xs, ys, z, aspect_ratio = 1) isa Plot
@test wireframe(xs, ys, z, aspect_ratio = 1) isa Plots.Plot
# TODO: clims are wrong
end

Expand All @@ -202,7 +204,7 @@ with(:pgfplotsx) do
p2 = contour(x, y, Z)
p1 = contour(x, y, f, fill = true)
p3 = contour3d(x, y, Z)
@test plot(p1, p2) isa Plot
@test plot(p1, p2) isa Plots.Plot
@test_nowarn Plots._update_plot_object(p3)
# TODO: colorbar for filled contours
end
Expand All @@ -214,7 +216,7 @@ with(:pgfplotsx) do
y = t .* sin.(θ)
p1 = plot(x, y, line_z = t, linewidth = 3, legend = false)
p2 = scatter(x, y, marker_z = (x, y) -> x + y, color = :bwr, legend = false)
@test plot(p1, p2) isa Plot
@test plot(p1, p2) isa Plots.Plot
end

@testset "Framestyles" begin
Expand Down Expand Up @@ -250,7 +252,7 @@ with(:pgfplotsx) do
u = ones(length(x))
v = cos.(x)
pl = plot(x, y, quiver = (u, v), arrow = true)
@test pl isa Plot
@test pl isa Plots.Plot
# TODO: could adjust limits to fit arrows if too long, but how ?
# mktempdir() do path
# @test_nowarn savefig(pl, path*"arrow.pdf")
Expand Down Expand Up @@ -461,4 +463,15 @@ with(:pgfplotsx) do
@test isfile(fn)
end
end

@testset "Unitful interaction" begin
yreg = r"ylabel=\{((?:[^{}]*\{[^{}]*\})*[^{}]*?)\}"
pl1 = plot([1u"s", 2u"s"], [1u"m", 2u"m"], xlabel = "t", ylabel = "diameter")
pl2 = plot([1u"s", 2u"s"], [1u"m/s^2", 2u"m/s^2"])
pl1_tex = String(repr("application/x-tex", pl1))
pl2_tex = String(repr("application/x-tex", pl2))
@test pl1_tex[findfirst(yreg, pl1_tex)] == "ylabel={diameter (\$\\mathrm{m}\$)}"
@test pl2_tex[findfirst(yreg, pl2_tex)] ==
"ylabel={\$\\mathrm{m}\\,\\mathrm{s}^{-2}\$}"
end
end
10 changes: 9 additions & 1 deletion test/test_quality.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,15 @@
Aqua.test_all(
Plots;
stale_deps = (;
ignore = [:GR, :CondaPkg, :Contour, :Latexify, :LaTeXStrings, :Requires]
ignore = [
:GR,
:CondaPkg,
:Contour,
:Latexify,
:LaTeXStrings,
:Requires,
:UnitfulLatexify,
]
),
project_toml_formatting = false, # issues since weak deps
ambiguities = false,
Expand Down
Loading