Skip to content

[BUG] draw_arrow attribute overrides second axis styles in PGFPlotsX #5166

@Simon-Brandt

Description

@Simon-Brandt

Details

When using the draw_arrow attribute with PGFPlotsX as backend, the axis styles on a second axis are overridden. For me, setting the font size for the axes guides is respected on the primary x and y axis, but ignored on the second y axis.

With the following example script, we create a bar plot without arrows on the axes ends, and all font sizes are correct. As soon as we uncomment the draw_arrow=true line, we get the expected arrows, but the font size on the second (right-hand) y axis is reduced to the default size. (Note that I intentionally made the second bar plot invisible, as for my use case I'm only interested in the axis and overlaid bars would confuse, here.)

#!/usr/bin/env julia

using Plots

pgfplotsx()
plot_attrs = (
    legend=false,
    xlabel="x label",
    ylabel="well-sized y label",
    guidefontsize=24,
    tickfontsize=10,
    # draw_arrow=true,
    tex_output_standalone = true,
)

plot = bar(
    [1, 2, 3, 4, 5],
    [0.1, 0.5, 0.3, 0.2, 0.4];
    plot_attrs...
)

bar!(
    twinx(),
    [1, 2, 3, 4, 5],
    [0.1, 0.5, 0.3, 0.2, 0.4];
    plot_attrs...,
    xlabel="",
    ylabel="mis-sized y label",
    seriescolor=false,
    linecolor=false,
)

savefig(plot, "tmp.tex")

See the output for draw_arrow=false here and for draw_arrow=true here.

Solution

After quite some time, I found that setting the draw_arrow=true attribute changes the usual PGFPlots key axis y line* to its non-starred counterpart axis y line (and the same for the other axes). This correctly adds the arrow, but also affects other parameters. The PGFPlots manual states:

The starred versions line* only affect the axis lines, without correcting the positions of axis labels, tick lines or other keys which are (possibly) affected by a changed axis line. The non-starred versions are actually styles which set the starred key and some other keys which also affect the figure layout:

This wouldn't be an issue by itself, but Plots.jl sets axis y line as one of the last PGFPlots options. When moved before all other options for the y axis, the following options override the values which the non-starred axis y line sets, thus also correctly setting the font size.

Better still (and perhaps easier to implement) would be to always use the starred axis y line* and instead set another parameter to the y axis line style: When y axis line style={..., -stealth} is set, the arrow is drawn, but the other axis options aren't overridden. I guess this would be the way to go. See the then-correct output here.

NB: -stealth is a special TikZ style used in several examples in the PGFPlots manual and described for quiver plots:

The -stealth is a TikZ style which configures outgoing arrow styles of type ‘stealth’.

As far as I can see, the problematic setting of axis y line occurs in:

# framestyle
if framestyle in (:axes, :origin)
push!(
opt, # the * after line disables the arrow at the axis
"axis $letter line$(axis[:draw_arrow] ? "" : "*")" =>
(axis[:mirror] ? "right" : framestyle :axes ? "left" : "middle"),
)
end

whereas the y axis line style is set in:

push!(
opt,
"$letter axis line style" =>
if !axis[:showaxis] || framestyle in (:zerolines, :grid, :none)
"{draw opacity = 0}"
else
pgfx_linestyle(
pgfx_thickness_scaling(sp),
axis[:foreground_color_border],
1,
)
end,
)

Likely, moving the draw_arrow conditional expression to the style setting to get -stealth as additional PGFPlots option, while always setting the starred axis . line, would solve the issue. At least it did by manually doing so in the output LaTeX file. I just don't have an answer for why this seemingly only happens with second axes.

Backends

This bug occurs on ( insert x below )

Backend yes no untested
gr (default) x
unicodeplots x
pythonplot x
pgfplotsx x
plotlyjs x
plotly x
gaston x

Versions

Plots.jl version: 1.40.11
Backend version (]st -m <backend(s)>): 1.6.2
Output of versioninfo():

Julia Version 1.11.5
Commit 760b2e5b739 (2025-04-14 06:53 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: 8 × Intel(R) Core(TM) i7-1068NG7 CPU @ 2.30GHz
  WORD_SIZE: 64
  LLVM: libLLVM-16.0.6 (ORCJIT, icelake-client)
Threads: 1 default, 0 interactive, 1 GC (on 8 virtual cores)
Environment:
  JULIA_EDITOR = code
  JULIA_VSCODE_REPL = 1

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions