Plots.jl: Better axis formatter tools

Created on 28 Aug 2016  Â·  8Comments  Â·  Source: JuliaPlots/Plots.jl

There's a very common pattern, where there's a "numeric" type which has a better string representation than a standard float. Some examples:

  • Date
  • DateTime
  • TimeOfDay
  • Price / Currencies
  • SIUnits

I'm brainstorming on a nicer way to handle these rather than making a type recipe for each and hacking the axis formatter. Possibly by registering the type/abstract in a Dict{DataType, Function} which is checked against series data when computing the default format?

The steps would likely be:

  • Make convertToAnyVector more permissible for AbstractArrays of unknown types, so that the registered types can flow through without immediate conversion
  • When the processing is finished, convert and add the formatter function to the proper axis

For anything of this pattern, you could forego the type recipe and instead add it to this "type formats dict", and everything would flow through nicely.

Of course if I get around to implementing the "PlotSpec" concept, lazy attribute computation, and "dirtiness tracking", then this stuff would be easy because you could just check the type of the original data and you're done.

enhancement

Most helpful comment

By the way, the recipe idea is very clever, and elevates this package from great to must-have. Nice work, and I hope you continue to refine these ideas!

All 8 comments

Can I add a request for:

plot(... ; formatter=:none))

As a shortcut/synonym to this:

plot(... ; formatter=((x)->""))

Also, is it possible to have different formatters for the x vs y axis?

1) sure. 2) xformatter or yformatter both work. (In fact you can prepend
the axis letter to any axis attribute)

On Sunday, August 28, 2016, Alex Williams [email protected] wrote:

Can I add a request for:

plot(... ; formatter=:none))

As a shortcut/synonym to this:

plot(... ; formatter=((x)->""))

Also, is it possible to have different formatters for the x vs y axis?

—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/tbreloff/Plots.jl/issues/460#issuecomment-243000289,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AA492r8G57mOUq3MQl8NuHyr4klfN_Coks5qkfwqgaJpZM4Ju00W
.

You may be interested in my attempts at getting axis formatting working nicely with Unitful.jl. I put the plot recipes in a new package UnitfulPlots.jl.

One thing I encountered was that I couldn't use a type recipe because if I did, there was no way of knowing whether to use xformatter or yformatter (the type could appear in any argument position for plot). So I fell back to user recipes, which required some extra complications to do the obvious thing if ordinary numbers and quantities were mixed on different axes. I just started playing around with this, so maybe I misunderstand how to use these recipes. Anyway, what I have seems to work for the obvious cases.

Is there a way to format the color bar? cformatter doesn't seem to exist and zformatter doesn't affect the color bar. At present I'm not sure how to make units appear on the color bar if doing a heat map, for instance.

cc @ChrisRackauckas who was playing around with SIUnits, I think.

My SIUnits recipes just chop out the units so they can plot, so since you made it show units anywhere you got further than me :+1: .

The only issue is, don't user recipes apply before type recipes? So for example, if my solution type has sol.t for time and sol.timeseries for the timeseries information, my recipes tend to just transform plot(sol) into plo(sol.t,sol.timeseries). If the user recipe is applied first, then this will still error in the case where t and timeseries have units. Is that the case @tbreloff ?

Excellent @ajkeller34. Yeah I've come up against that type recipe problem... it's kinda tricky because you don't necessarily know what axis the units will be applied to when the type recipe is called. The correct way to handle would be to turn the data into a (data,formatter) pair that gets passed all the way through. Then once the data "lives on an axis" it can update the axis formatter and apply the conversion.

User recipes should work fine... you just lose the "one line makes everything work perfectly" benefit of type recipes.

By the way, the recipe idea is very clever, and elevates this package from great to must-have. Nice work, and I hope you continue to refine these ideas!

So the current solution that I just added to the dev branch, is to hack type recipes for AbstractArrays. When Plots encounters an array that it may not know how to handle, it applies a type recipe on the first element and checks to see if a 2-tuple of functions is returned. If it is, then it assumes that the first function takes in the element type and returns something Plots can handle, and the second function takes in a number, and returns a tick label string. See https://github.com/ajkeller34/Unitful.jl/pull/21 for an example of how you would take advantage of this.

I'm going to close this until someone complains that this solution isn't good enough. :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

crstnbr picture crstnbr  Â·  3Comments

asinghvi17 picture asinghvi17  Â·  3Comments

kleinschmidt picture kleinschmidt  Â·  3Comments

dancsi picture dancsi  Â·  4Comments

cortner picture cortner  Â·  4Comments