Plots.jl
Plots.jl copied to clipboard
[FR] Colorbar properties
It would be useful to be able to style additional attributes of colorbars, as discussed recently on slack in plotting
~- [ ] tick size~ ~- [ ] tick color~
- [x] ticks
- [x] tick scale
- [x] tick font
- [x] tick font size
- [x] tick font color
- [ ] border color
- [ ] border thickness
- [ ] bar width
- [ ] bar height
- [ ] other things?
My use-case is cleaner map-plotting recipes in GeoData.jl. Currently, if you stray too far from the defaults the colorbar starts to look out of place.
This could start with just GR?
related, but just for ticks: https://github.com/JuliaPlots/Plots.jl/issues/2308
It's tricky because Plots development aims to keep keywords few(-ish), in order to keep maintainability. In general all new keywords should preferably be applied across all backends to keep interchangeability of backends. One possibility could be to adapt extra_kwargs
to be able to pass colorbar kwargs, but this wouldn't work in recipes. I guess this requires a bit of discussion.
@rafaqz do you happen to know how many of these attributes are supported natively by e.g. GR?
I think the colorbar should have the same attributes as an axis. For example just like you have xticks and xscale, the colorbar should be able to support cticks and cscale. I came across this limitation while attempting cscale = :log10 (also tried zscale = :log10) on a heatmap.
I can see how keeping the keyword scope down would be important! especially given the breadth of use cases Plots.jl has to deal with.
If we can use the same set of attributes as @hervasa2 suggests, (maybe with colorbar_
prefixed?) it would at least add less overhead in terms of new names for things.
I'm not sure what is possible with GR, the colorbar
method doesn't have many arguments, but there is lot of global state that is incorporated somehow. It does seem possible to do with matplotlib, plotly, and pgfplots.
So having a new keyword type colorbar
in addition to Plot
, Subplot
, Axis
and Series
, and reusing Axis
keywords while prepending colorbar_
? That does sound like a neat design. Thoughts @daschw ?
Also I didn't read @hervasa2 comment properly, cticks
etc is nice too for where x/y is usually used.
So having a new keyword type colorbar in addition to Plot, Subplot, Axis and Series, and reusing Axis keywords while prepending colorbar_? That does sound like a neat design. Thoughts @daschw ?
I think that sounds like a good approach.
Yes colorbar_[keyword] with c[keyword] as an alias would be nice and intuitive. I think a minimal feature in GR (if not all axis attributes can be applied to the colorbar) would be colorbar_ticks, that way the user could manipulate the data behind the scenes and set manual ticks to achieve the desired result.
There is clims
at the moment
I would also very much welcome the ability of manipulating colorbar properties. Thanks for bringing this up!
I'm also looking for this functionality. Asked for exactly this in Slack and was directed here
I think it would be nice to be able to access the frame/border/axes of the colorbar as well, e.g. colorbar_frame/cframe=:box
.
related: #2345
If anyone is willing to help out with the development of this, please help out with the testing in the PR
@rafaqz and others, most of the requested changes have been merged, please let me know your comments. Currently only PyPlot backend supports the new colorbar args:
:colorbar_fontfamily => :match,
:colorbar_ticks => :auto,
:colorbar_tickfontfamily => :match,
:colorbar_tickfontsize => 8,
:colorbar_tickfontcolor => :match,
:colorbar_scale => :identity,
currently no c_*** aliases are made yet, but let's first make sure this works
Thanks, I'll try to give some feedback in the next few days
Naturally you'd need to use #master branch before we get a relase
These work perfectly for me. Although I'm not sure what the allowed values for colorbar_scale
are?
It would be good to add a few controls for the colorbar border too, like color/width etc. Seems it may be easy to copy your PR now to add some related args :)
colorbar_scale takes :log10, :log2 and :identity (same as axis). Regarding the border and the color, it is strange that you want to change it even. Right now pyplot has 5% border width of the main plot, and I have no idea what do you wish we could've controlled the color
Oh right yep scale works well too.
With color/width - there are situations where you don't want a border on the colorbar, or you want it to be less prominent. For example, if you use e.g. :border=:none
the plot has no border, but the colorbar still has one, and it doesn't look great. You may also want to use e.g. a ligher grey border instead of black, or use a thinner border, to push the colorbar back and make the plot stand out more. That being said, the PyPlot colorbar does look alright as-is most of the time, GR less so.
But I can add this later.
Thank you for working on this! colorbar_scale
is working nicely; however now the problem is the color gradient itself. When the colorbar_scale
is switched to :log10
the color gradient follows it likewise. Therefore, once colorbar_scale = :log10
is set only the colorbar changes, and not the actual colors on the heatmap. When I tried to manually fix this by using something like cgrad(:inferno, scale =:exp)
I came across the bug reported on #3420. pyplot no longer respects a color gradient's scale
Right, I've been aware of this for a while. The attempt to fix was here #3432. I need some additional testers
Right now this is a pyplot issue right? I just want to make sure that simplest behavior is still functional. Please let me know if
- Normal linear scale colorbars work as intended with pyplot
- Markers are not properly colored with the log scale colorbar.
Thanks for your quick response! Yes this is a pyplot issue only.
- Normal linear scale colorbars work as intended with pyplot. Base functionality looks fine.
- Markers are not properly colored with the log scale colorbar. This applies both to the cases where one uses
colorbar_scale = :log
or whencolor = cgrad(:inferno, scale =:log)
In the meantime I will test #3432
I think the first order of business would be to get color = cgrad(:inferno, scale =:log)
working again since this is something that was broken.
Then I like the axis formatter approach suggested by @isentropic in #3432:
"Can't Plots just provide axis formatters? For example: I am plotting a 10^2, 10^3, 10^4 (three points) in log scale, Then, Plots would just log it to get -> (2, 3, 4) Then, just decorate the axis labels as (10^2, 10^3, 10^4) (instead of natural 2,3,4)"
I'm not sure how to handle colorbars with log scale right now. I don't think we should focus on (cgrad=:log) just yet. In the pr Cscale=log produces normal looking colorbar (color transition in the gradient looks uniform). However the markers are wrong color.
The problem is that I'm not so sure where Plots assigns marker colors to the points . If someone has an idea do let me know.
Marker colors are stored in the marker_z
seriesattribute, but maybe I got the question wrong
Yes, I'm aware of that, but where does it get assigned? Somewhere in the depths of the pipeline but I could not find where
Aren't those given from the callsite? Or do you have examples where there is automatic color assignment?
In case of the colorbar, I think the colors need to be assigned somehow? Perhaps I'm missing something here but I thought marker color gets overriten when a colobar is present
Its the other way around. You get a colorbar of you got marker_z values. How should Plots now what values to put there?
@hervasa2 @rafaqz checkout the PR https://github.com/JuliaPlots/Plots.jl/pull/3620
need testing and feedback from you
Thanks for the work on this! Is there any progress especially on the log scale colorbar? What is stopping us from merging #3620?
Lack of testing and user feedback
That PR is outdated I believe, given a large demand I could revise it.
Hmm, I don't know if I myself can be representative for a large demand... But for certain the lack of smooth support of log scale colormap/colorbar is one of the reasons I would still prefer matplotlib in production work. I don't feel urgent on this feature since we do have other alternatives, but it's good to have one and maybe I can help test the features and give feedbacks.
The reason I'm hesitant to merge it is that the colors did not look right to me sometimes. Dangerous decision to plot something that is not representing the actual data. Need to test this thoroughly.
My personal workaround is just to log the data preemptively.
I actually have a use case where taking the log on the data cannot work: a histogram2d
with weights.
x = rand(1000)
y = rand(1000)
w = 10 .^(10 .* rand(1000))
histogram2d(x, y, nbins=20, weights = w)
In this case I really need a log scale colorbar.
Lack of testing and user feedback
Sorry I thought I had already tested the new functionality and it was merged?
What was added with the second PR that was different to before? A description for the PR would help with feedback.
The second PR actually fixes logscale colors
First time the color reflected in the colorbar was not matching the data
Other backend are still to support the colorbar_scale
feature. For example, with PGFPlotsX: