Makie: defaulting to minus symbol everywhere?

I have the feeling that this problem has already been solved, but I haven’t been able to locate the solution.

Basically, I want all numeric labels and letterings for negative numbers to use the unicode minus symbol, not the ASCII hyphen character. I imagine that there is a simple global switch or a simple switch to the number formatter . . . But, as in the discussion I link at the end of this message, it seems that you are supposed to write your own number formatter and probably I would be able to achieve my goal by doing so. (If that’s the only way, I would like to know how to write a smart formatter that can handle various cases like “1.0 x 10^{-n}”. A much simpler way would be to get hold of the result of Makie’s native formatter and replace the hyphen symbols, if any, with minus symbols.)

For visualization, the minus symbol, if available, is almost always the better choice than the hyphen. I guess Makie defaults to the hyphen only for backward compatibility or to be conservative considering that some fonts cover only a very limit set of characters.

Here is a little toy program to demonstrate that Makie uses the hyphen whereas Plots.jl uses the minus symbols:

using CairoMakie
using Plots

xs = -π:(π/16):π
vals = cos.(xs)

minus2  = "−2"
hyphen2 = "-2"

let fig = Figure(; fontsize = 28) # font="Lucida Grande"
  ax = Axis(fig[1,1])
  lines!(ax, xs, vals)
  text!(fig.scene, Point3f(0.25,0.12, 0); text = minus2, color=:red,
        space=:relative)
  text!(fig.scene, Point3f(0.25,0.08, 0); text = hyphen2, color=:blue,
        space=:relative)
  save("tmp-Makie.png", fig)
end

let p = Plots.plot(xs, vals)
  annotate!(p, -2, -0.85, Plots.text(minus2,  :red, 10))
  annotate!(p, -2, -0.95, Plots.text(hyphen2, :blue,10))
  savefig(p, "tmp-Plots.png")
end

As an alternative (workaround), I want to switch to the “Lucida Grande” font, which comes with macOS, because its “hyphen” is long and thin enough to look like a minus symbol. But adding font="Lucida Grande" to Figure() changes only the font used by text!() and the tick font remains the default one.

https://discourse.julialang.org/t/setting-font-of-minus-sign-in-exponent-in-makie

1 Like

FWIW, my workaround is to replace(..., "-"=>"−") the hyphens “manually”. E.g., on the axis tick labels, you can do

f = Figure(resolution=(300,300))
ax = Axis(f[1,1], xtickformat = x -> [replace(string(x), "-"=>"−") for x in x])
lines!(ax, -10:10, -10:10)
f

which gives (note the minuses of the x-axis vs the y-axis)

Arguably, shouldn’t Makie itself default to minus instead of hyphen?

2 Likes

I had a PR doing this change once but it was not accepted. Mostly because it’s breaking and the minus takes more space so you get collisions more easily.

Also you could write a meta formatter which formats tick labels according to some other formatter but then replaces the hyphen with minus as shown above

2 Likes

Thank you everyone for your help and inputs.

breaking

I understand, but I wonder whether it is difficult to introduce a switch instead of changing the default?

get collisions more easily

I already get a lot of collisions :slight_smile: without changing the formatters. Unfortunately, collisions seem to be something the user have to manually avoid in any case. (Of course, I’m not missing your point of “more easily”. My point is that the potentially increased frequency of collisions shouldn’t be regarded as an impediment to the introduction of the minus symbol.)

[By the way, currently I want to change the minus symbol on a colorbar, which means I have to find out the name of the formatter of the colorbar . . . And what about the global font change? If I can switch all the fonts to “Lucida Grande”, I can forget about this issue :slight_smile: ]

That’s exactly what I was thinking of when I was saying I might be writing a custom formatter. How do you get hold of the result of the default formatter for you to modify? If I knew the name of the default formatter, then I imagine this is what I would do:

myformatter(xs) = replace.(MakieDefaultFormatter(xs), "-" => "−")

This should answer both questions:

Base.@kwdef struct HyphenFormat
    wrapped = Makie.automatic
end

function Makie.get_ticks(ticks, scale, formatter::HyphenFormat, vmin, vmax)
    ticks, labels = Makie.get_ticks(ticks, scale, formatter.wrapped, vmin, vmax)
    return ticks, replace.(labels, "-" => "−")
end

f = Figure(; fonts = (; regular = "Comic Sans", bold = "Times Bold"))
ax = Axis(f[1, 1], title = "Bold font", xtickformat = HyphenFormat())
scatter!(ax, randn(100, 2))
f

4 Likes

We can detect if collisions happen, but we cannot really change ticks depending on size in layout because the ticks influence the layout so you get a cycle.

Matplotlib does this, with an option to turn it off; it’s a shame that Makie doesn’t follow suit. Using a hyphen seems like poor typography here.

Are you referring to Makie#2321? My understanding is that the hyphen change wasn’t rejected outright, but was requested to be put into a separate PR rather than being a small part of a much larger PR, so that it could be discussed/evaluated on its own.

I have a second cent on this, that is: should tick labels be so closely packed that a hyphen/minus symbol makes the difference between overlap and no overlap, the plot has bigger issues.

1 Like

well, sure, but in a normal sentence you also rely on gaps about the size difference between hyphen and minus glyph to break the words apart :slight_smile: Sonothavingthatgapcanmakequitethedifference

Anyway, as you can see from that old PR I was never opposed to minus glyphs

Are you referring to Makie#2321

Not just that, also conversations off github. I guess the time to change it could be now because it could be bundled up with all the others in 0.20 @sdanisch ?

4 Likes

Thank you! This is off topic, but just to correct myself:

fonts

I thought that didn’t work for me and that was the reason why I asked the question. But staring at your code, I finally discovered that I spelt it as font (because I thought you just set one default font). Incidentally, in a different context, I recently found that Makie silently ignores unknown keywords, which was why I didn’t realize my misspelling.

We switched to the minus symbol in Makie 0.20

4 Likes

In particular:

1 Like