Plots.jl clean scientific formatting

Suppose I have a plot p. If I want to change the y-axis to scientific formatting, I can do:

plot!(p, yformatter = :scientific)

Now a tick label that was previously: 30000, becomes 3x10^4.

However I don’t want each single tick label to display, e.g.: 3x10^4, 4x10^4, …

It would be nice to have each tick label display: 3,4,…

and have the “x10^4” at the top of the y-axis. I can’t find an easy option to do this, short of manually annotating the tick labels and adding the “x10^4” as an annotation. Does anybody have a better way?

Thanks a lot in advance!

1 Like

I suppose one could use the same strategy as in UnitfulRecipes.jl. I.e., do a bit of work (with @printf?) to extract the right power of 10 for all y values (let’s say it’s 14), divide them by 1e14, add " (×10¹⁴)" to the y-axis label, and reset the yformatter value?

1 Like

You might want to try out different plotting backends. Some might already do what you want - though you might have to use backend-specific code to get that to work.

Example: inspectdr() backend

InspectDR already does scientific notation that way. Actually, it displays using what is called “engineering notation” by default: it only displays powers that are multiples of 3 (…, x10^-6, x10^-3, x10^-0, x10^3, x10^6, …). But you can switch it to real “scientific notation” and display intermediate powers (like x10^4) as well.

Here are a few examples:

SI labels

Note that the bottom plot was configured to display time using so-called “SI notation” instead of “engineering notation”. The x-axis label is set to “n” - which, of course is equivalent to x10^-9.

Configuring axis labels

The bottom-most plot uses a “plot template” called transientplot() (defined in src/templates.jl). It is used to overwrite the default “engineering notation” in order to display SI units through the NumericIO.jl module:

plot.layout[:format_xtick] = TickLabelStyle(NumericIO.UEXPONENT_SI)
plot.layout[:format_ytick] = TickLabelStyle(NumericIO.UEXPONENT_SI)

Note that there are other formats available, including different versions of engineering/scientific formats that can display the multiplication factor as one of the following:

  • E-3
  • x10-3
  • ×10⁻³ (Using UTF8 characters (more aesthetically pleasing)

I prefer the UTF8 notation of course, but some fonts do not include the glyphs for superscript numbers, so you can switch to less aesthetically pleasing alternatives, if need be.

Configuring axis labels: Part 2

You can also set defaults for how InspectDR displays tick axis labels in Julia’s config file, ~/.julia/config/startup.jl:

DEFAULTS_INSPECTDR = Dict(
	:notation_x => :SI,   #Change x-axis notation (:SI/:SCI/:ENG)
	:notation_y => :SI,   #Change y-axis notation (:SI/:SCI/:ENG)

But you have less control using this technique.

4 Likes

I’m not sure I can think of a better solution to manually annotating the graph for the label at the top of the y axis but I just wanted to point out that the formatter keyword argument accepts a function so you could do something like this:

using Plots

x = 0:20
y = 10_000:500:20_000

y_formatted(y) = y / 1_000

plot(
    x,
    y,
    formatter = y -> y_formatted(y),
    legend = false
)

To get this:

y_formatter

3 Likes

I have always found that confusing. Why not just label the axis as y/10^14?

3 Likes

I hadn’t heard of this package. It looks great and I will have a playaround. I sometimes need Nyquist plots, which this looks perfect for. WRT this problem… I’ve already just solved it just using the ‘ugly’ method I proposed.

That’s a good idea in general. I never think of doing that due to…cognitive inertia?

In this particular case, I have a specific “weird” setup that precludes this solution. I have a grid of plots. Each element of the grid has a different /10^x. I only want to explicitly write the x-axis and y-axis labels on one of the grid elements. So I’d like the y-labels to be the same for each grid element.

yep, basically did this, except using an annotation rather then the y-axis label. thanks!

That sounds like a confusing plot for a user to understand…

As I know, this is a default setting in matlab and I think that there are many people want it works in GR backend of julia. In a publication, the “clean scientific formatting” looks space-saving and neat.

Well, maybe it could solve the problem NOW. But we hope that it works automatically, not manually. For some cases, the data has 10^14 scale, for other cases, the data has 10^-3 scale… we can’t manipulate them all.