-
-
Notifications
You must be signed in to change notification settings - Fork 313
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Transition to Plots.jl #8
Comments
I'm all for this. If it fixes the first-time-to-plot issues and formalizes the backend handling to get rid of the conditional dependency issues, that's worth a fresh start IMO To me that roadmap makes sense. |
The plan makes sense until point 5, but I think before deprecating Plots.jl there are several things that would need to happen and may not be trivial to get:
|
Precompilation should work better, so indeed with GR it should be much faster. I'm also experimenting with julia-static, but haven't gotten any answers from e.g. @vtjnash about some of the problems I run into.
that's point 3, isn't it?
I'd love to just have our own webgl backend ;) If you don't use webgl, you might as well just embed an svg in html! But Plotly and PGFPlots would be great! I guess anyone can help with those once we have a reference backend! |
Hi Simon, The reason I'm invested in Plots is that it has 1) the recipes, allowing all plotting to be based on methods for custom types by essentially removing the need for packages to depend on a plotting library; 2) the terse, smart syntax, and 3) the ability to split backend from interface/syntax. It looks like a reimplementation of Plots based on MakiE could resolve the problems while keeping the advantages. MakiE appears modern, and I agree that now, pre-julia-1.0, is a great time to allow some drastic changes to Plots internals. With regard to your roadmap, I agree completely that it would make sense to have two development paths (Plots.jl and MakiE.jl) until we have shown that MakiE can attend feature parity with current Plots. There's been a lot of development on Plots (there's close to a new PR merged every day and have been for a long time, though many PRs are small), and many of the fixes and improvements are fairly subtle and based on users making literally hundreds of thousands of real-world plots with the package. So the question is, how do we ensure that all of that experience isn't lost? I think one good approach could be to go through all the PRs from the last year and ensure that the functionality and corrections they've added is reflected in the current examples (doubling as tests). We've become better at doing that, but there was a long period where that wasn't in place. We'll add some new examples to make sure this is so, and those examples could then serve as a development target for MakiE - essentially, when they pass we'll know we're at feature parity. With regards to deprecating Plots vs renaming the new MakiE to Plots and replacing the library when it's ready I don't have any strong feelings about this, although Plots is the better name IMHO. If MakiE has feature parity and can be used with the same syntax and backends, while resolving the issues, I see no reason it shouldn't replace the current Plots library. One thing you might consider now is whether to put the library in the JuliaPlots org? I think we could still set it up so only you have owner and push rights to the Repo. I think that would help to put it on the radar for the other members of the org if you'll like us to engage with the project, and could also make it easier to coordinate things. Instead of moving things over from Plots we could consider parceling out some of the functionality that could be used unchanged in MakiE in a separate package, which Plots and MakiE would then both depend on. I don't have a good enough overview of MakiE to identify exactly what those things are, but could be e.g. the recipes and arg files, much of the backends etc. |
I am looking forward to the Cairo backend. This will smoothly integrate with Gtk.jl. |
👍 to everything @mkborregaard wrote.
If I understood this correctly this sounds a lot like @mkborregaard's suggestion here:
and I do like that a lot :-) |
I want to stress @mkborregaard words here. These Plots.jl features are quite important. No one wants to go back to ugly syntax or to a scenario in which recipes don't work well. |
Yes, that's the plan! Recipes will actually be much more first class and probably more flexible. @daschw this is pretty much the plan :)
Yes, I like this too! Since the higher level syntax itself will basically just be a bunch of recipes, switching out the interface should become more natural!
I was sure that I already answered this. It would indeed be lovely, if we can grow the plots.jl testing suite before making a switch! Maybe that's something the community can do during the next month! We should announce this somewhere, that everyone who had a problem with Plots.jl should open a pr with a small code snippet reproducing that problem! |
No need for that, IMHO. Everybody who approaches us with a real issue are suggested to open an issue with an MWE. We currently have 219 open issues, and the list is quite up-to-date – reading through those should give a very good impression of the shortcomings that would be relevant to address. What I meant was to ensure all recent fixes and enhancements were covered by tests. I'll open an issue to track this. |
well, making a testsuite out of it ( prs, issues, anything) and not having a bunch of issues is exactly what i meant to call for ;) |
Do you mean making a testsuite out of things that aren't fixed yet? Nice idea, but tests would have to work different than they currently do in Plots (they compare plots to a reference image). |
I don't really understand what you mean... I don't really care if the source of those tests are issues, prs or whatever ;) It also shouldn't matter much, whether they're against a reference image, or if I need to run them in Plots.jl and MakiE and compare them myself. It's just important for me, that these are at a single place and quickly to execute, because it will be a painful process even under perfect circumstances ;) |
This: https://github.com/JuliaPlots/Plots.jl/blob/master/test/runtests.jl#L3-L16 It runs all the examples (https://github.com/JuliaPlots/Plots.jl/blob/master/src/examples.jl) and compares the output to reference images stored here: https://github.com/JuliaPlots/PlotReferenceImages.jl/tree/master/Plots When those tests pass, there should be feature completeness (well, StatPlots, PlotRecipes and all package recipes should work as well for feature completeness, we'll work on building a similar system for them). (I first thought you were talking about tests-first programming.) |
It would be nice if, like in Plots, there would be a lightweight package like RecipesBase - so that packages don't have to require MakiE itself to define recipes. |
Whenever there will be a nice way to define recipes with Makie, it will be as lightweight and future rich as in RecipesBase :) |
I'll volunteer to help with histogram recipes. :-) |
Great to hear! If you want, you can already start opening issues with recipes you'd like to port... So that I can already have an idea of how they look, even though that it doesn't really make sense to port them just yet. |
Concerning histograms, I'd initially aim for porting
It would also be cool to have 2D histograms with a 3D-Lego visualization like this: https://root.cern.ch/js/latest/?nobrowser&file=../files/histpainter6.root&item=draw_hstack;1 (lower right corner, fully interactive). This is a ROOT plot, via JSROOT. It can do awesome stuff in WebGL now, would be great so have such things in Julia. |
So is it officially not your policy anymore to be able to use Plots recipes? I'd say that's a rather big disappointment. |
The very key idea is to have one recipe format that can be used by packages to define plotting, regardless of what plotting solution they would require. I'd be OK with changing the syntax of Plots recipes somewhat to accomodate flexibility, but I think the whole effort is not going to be helped by having competing recipe syntaxes. |
Some level of compatibility, recipe-wise, would indeed be awsome. |
@mkborregaard I think I've said that multiple times now, but I guess not explicit enough: I will play around with my own non magical way of defining recipes, relying more on generic, extendable constructs. Which will need some testing material - e.g. currently existing recipes. It is planned to just put a compatibility layer on top of that for old recipes, once I've confirmed that I cover the same functionality. Then we can see which way is more intuitive for the user, and either the compatibility (aka the old recipe style) becomes the official way, or if enough people agree that the new way is superior, i would recommend to slowly deprecate the old way. |
No you did say that very clearly - I just thought there's a big step from that to having to port all the existing recipes, such as histograms. Never mind. I am a bit stunted at the moment from trying out MakiE because I can't get the install to work, I think my Pkg is broken... |
Actually, porting the histograms shouldn't be too bad, since we get a lot of functionality from StatsBase now. If course the devil is always in the details (e.g. log-scales), but still. But a recipe compatibility layer would be great! |
I'm definitely not planning to abandon Plots any time soon - but there's some things I'd like to do with histograms that will need interactivity. |
Sorry I was out of line. |
If you're going to consider rethinking recipe definitions, please try to keep units support in mind. I was never totally satisfied with Plots recipes when it came to that. I'm not sure how much of my troubles were fundamental to the design of Plots recipes or simply due to missing implementation details. One gotcha was that it was not possible to use recipes to append text to an axis label. If I have a time axis, I can use Plots recipes to label each axis tick as numbers with units (1.0s, 2.0s, 3.0s...), but I can't actually label the axis instead. One would rather have pure numbers on the axis ticks and "Time [s]" on the axis label. You can see UnitfulPlots.jl for an example of how far I got using Plots recipes, although the package is sort of broken at the moment by recent changes to Unitful. Perhaps it could have be implemented more cleanly now. The documentation for recipes was somewhat confusing at the time I wrote the code. |
Let me understand why you couldn't simply do |
Yes. Or rather, I wasn't expecting it, but I was hoping for it... see PainterQubits/UnitfulPlots.jl#5 for some related discussion. |
I still think that's way more work than necessary. Just: NumberOrQuantity = Union{Quantity,Number}
@recipe function f(val1::AbstractVector{S}, val2::AbstractVector{T}, val3::AbstractMatrix{U}) where {S<:NumberOrQuantity , T<:NumberOrQuantity , U<:NumberOrQuantity }
if S<:Quantity
xlabel --> quantity_to_plot_string(S)
end
if T<:Quantity
ylabel --> quantity_to_plot_string(T)
end
if U<:Quantity
zlabel --> quantity_to_plot_string(U)
end
ustrip.(val1),ustrip.(val2), ustrip.(val3)
end You'll need to be careful to not hijack the all number version though. |
If I understand what you mean correctly, I'm not sure how I would avoid hijacking all number types by using a union type like that. When I try your suggestion, it just gets stuck in an infinite loop, probably applying recipes indefinitely since the signature will match vectors/matrices of There is a separate issue. The approach you suggest doesn't append the units. It actually replaces any x label you supply directly, so that e.g. Anyway, I don't mean to derail the discussion. All I'm saying is that unitful quantities are a nice test case to consider when thinking about how recipes should work and what they should be able to do, in my wholly unbiased opinion... |
That's why I said to be careful. Take that as psudo-code and do the transformation to avoid the issue. Here's one way: @recipe function f(val1::AbstractVector{S}, val2::AbstractVector{T}, val3::AbstractMatrix{U}) where {S<:Quantity , T<:Number, U<:Number}
xlabel --> quantity_to_plot_string(S)
ustrip.(val1),val2,val3
end
@recipe function f(val1::AbstractVector{S}, val2::AbstractVector{T}, val3::AbstractMatrix{U}) where {S<:Number, T<:Quantity , U<:Number}
ylabel --> quantity_to_plot_string(T)
val1,ustrip.(val2),val3
end
@recipe function f(val1::AbstractVector{S}, val2::AbstractVector{T}, val3::AbstractMatrix{U}) where {S<:Number, T<:Quantity , U<:Number}
zlabel --> quantity_to_plot_string(U)
val1,val2,ustrip.(val3)
end is probably the one that works.
No, what I am suggesting makes it do "Time [s]" by default (or whatever EditThat's running into issues sense Plots is setting defaults to floats, which is probably related to JuliaPlots/Plots.jl#430 . Issue: JuliaPlots/Plots.jl#1247 |
I think it might make sense to drop Measures.jl and make a Unitful.jl extension replacement for it in order to have units directly in there, and that could then help with dealing with ppi issues and things like that. That's really digging into details though. |
Yeah, probably that would make sense. Regarding the labeling, that would of course work, but eventually it would be better if the description and unit were decoupled. In a perfect world, a user should be able to just provide the description via the usual mechanism and not worry about labeling the unit. There are plenty of times where you might have the same units for two axes, but they refer to different things (e.g. "pump power [mW]" and "probe power [mW]"). I guess this is drifting away from discussion of recipes but just ping me on slack or whatever if you want to discuss further. |
How about providing support for units via AxisArrays? It's based on Unitful - and this way, units would automatically be available to Plots if the user so chooses. |
I'd like to bring to your attention another feature that is missing in Plots.jl. Currently, there is no way to query lengths of objects inside of a plot recipe. I came across this limitation a while ago when I was trying to place objects in a plot relative to other objects already in the "scene". I am not sure if this problem can be solved efficiently, but I am sharing it here anyways. |
consider it as solved :) |
I took a good look through the Makie.jl design and give it an A+. In this comment JuliaPlots/Plots.jl#918 (comment) I laid out a design that would be precompilable or even statically compilable. Makie.jl successfully incorporates these ideas and results in a clean internal design that both has performance in mind and is easy to extend via standard usage of the Julia dispatch mechanism. It's a little different since instead of using a global type for the backend, the backend is tied to a type parameter on the current It has a lot of other nice design advantages allowing for animations and interactivity to be much smoother. One thing that I don't like is that the current installation is so tied to GLVisualize.jl. It's quite a big install and a major win for Plots.jl was how light the original installation was. Of course, this could just be because the beta has some backend code baked in that will eventually move to a separate repository. How you plan to handle this @SimonDanisch is a necessary detail. I think it should just be in a separate repository and users should just The proposed recipe system is based on function overloading also sounds to me like a major win. Plots.jl's recipe system, along with a lot of argument handling pipeline, had a lot of macros that made it very difficult to debug at times. By using functions like this, it'll give true line numbers and be much more compatible with future debugging tooling. There's one last performance note that I see in here and it's the use of lots of dictionaries. But this could be just a v0.6 thing and I talked to Simon about using named tuples in most places and it seems doable/sensible. There are a few places where dictionaries would still make sense though, like https://github.com/SimonDanisch/Makie.jl/blob/master/src/plotsbase/scene.jl#L27 to keep the mutability of scenes, but in the end it shouldn't be harmful to performance if they are not overused in the pipeline. I think that recipes should probably operate on dictionaries of kwargs or have an easy way to mutate/add to the NT. Also, it's paramount that recipes get their own repo so we don't need to depend on Plots.jl to use them. One thing I would like to see is the equivalent to Plots.jl's Makie.jl doesn't seem to have Plots.jl's sophisticated argument handling pipeline, but after a year or so of playing with it, I don't know if those aliases really help all that much. But that's something that seems like it can be added of Plots.jl people see fit (unless it's already there and I didn't notice it?) Thus, while I have been a very staunch advocate of Plots.jl, I always knew that it had some fundamental design flaws. I loved Plots.jl because its extendability via recipes was uniquely helpful for package development and was the only way forward for the Julia ecosystem. Makie.jl's design fixes the fundamental flaws of Plots.jl while having a sensible recipe design and a possible way to handle optional backends in a way that's dispatch-safe. For me, it's time to give up on Plots.jl and look at it as a stepping stone to Makie.jl. I am confident that it is built in a way that can address both our feature and performance needs, and am willing to put my hope and sweat into it. I'm not sure I'll have much time to contribute (well, I won't guarantee any), but I will guinea pig the recipe system and once things look stable, plan to be an early adopter for the switch. Well done @SimonDanisch, I hope we can work out the last few details. |
It's nice if recipes can be made more intuitive, though bear in mind that being able to use the current Plots' recipes (or being able to easily update Plots' recipes to MakiE format if we do end up making a clean cut replacement) is the key for Makie to provide all of the functionality in the Plots ecosystem.
👍
I don't think we need as many aliases as in Plots, though having both a short form for interactive use (
Are you saying "Makie is already so advanced that the thousands of Plots users can scrap it and go to Makie"? That would be good news, but it's not my impression. Or are you saying "Makie has the potential to fully replace Plots in time, and should thus be a focus for further development"? Which I essentially agree with. One thing Makie really needs is more people to start contributing to it. I believe that transitioning it to JuliaPlots might make it more obvious for members of that org to start spending time on it. Currently, there are so many open, important, issues on Plots, that it's not easy to find time to go learn a new codebase. |
The latter. Makie isn't advanced yet, but Plots.jl has fundamental design issues which need to get fixed, and Makie doesn't have those issues. So I'm keeping with Plots.jl for daily use, knowing that it needs to go away sooner rather than later if we really want to fix the performance issues. Also, the logic is just easier to understand. It really will be a great step forward if it gets feature complete, and if the recipes are placed in a low-dep repo that stays up to date (i.e. early and often tags so it always at least precompiles on release) then I plan to support it once it's available in all of DiffEq to help people start transferring.
That's a completely different thing though. Having specific helper macros is different than having the whole recipe being a macro. The
I'll just support both when it's ready. I hope it's a superset, but likely it won't be the same and that's okay IMO as long as the upgrade path is clear. |
Oh. I think that design could actually solve the concerns I have and make upgrading recipes quite simple. I wonder why I didn't think of that. I think attracting contributors is going to come automatically once Makie is at a stage where people start using it day-to-day. |
I also think Makie already look very promising and moving it to JuliaPlots would probably encourage Plots devs to contribute. As soon as the recipe mechanism is established, porting StatPlots would probably be a nice test to see how easy/hard the switch is. |
Yes, good idea. An alternative is to port the recipes.jl file in Plots |
Given @ChrisRackauckas comments above, that @piever has started porting StatPlots, and my own assessment of MakiE, I think it would make sense to commit more explicitly to porting the current Plots framework and ecosystem to Makie, if other members of JuliaPlots agree. My suggestion is to move Makie to JuliaPlots, then I'll step down as Owner of the org and give that place to @SimonDanisch . I will continue as a member, and @daschw (and @tbreloff , though he isn't active) will continue as owners of the org together with Simon, which should ensure that there is also a balanced focus in the org on developing Makie while keeping the nice features of Plots (and keeping Plots maintained for the large user base). Thoughts on this? |
You know that I would not want you to step down as owner @mkborregaard but everything else sounds great! |
I agree with @daschw! Should we get this started? |
Done. Welcome as owner, @SimonDanisch ! I'm really hopeful for the future of this. |
I'm moving from Python+Matplotlib to Julia and this discussion made me question: should I use Makie or Plots? One will replace the other? Merge in the other? Is there a recent follow up here? |
Not involved in this project at all, but
give an update on the status of the project generally as of July 2019 |
Hi! Is there any update on this? Cheers, |
Thanks, @SimonDanisch ! |
Considering that MakiE is designed quite differently from Plots.jl, any transition to Plots.jl will
basically mean replacing Plots.jl. I don't see how to slowly incorporate ideas from MakiE into Plots.jl without a huge amount of work. I think we're at a good time to still make drastic much needed changes, so we shouldn't try to be conservative here.
So I propose to let MakiE live as it's own package for a while until we can ensure, that all features from Plots.jl are well covered.
Then we can think about renaming MakiE, make a PR to Plots.jl to replace the internals with MakiE or simply deprecate Plots.jl and suggest to move to MakiE.
This would look something like this:
Other backends
I'm inclined to implement a reference backend different from GLVisualize with Cairo. I already have some code for this from my experiments in Visualize.jl.
Cairo is completely orthogonal to GLVisualize and offers missing bits and pieces like PDF/SVG export.
The orthogonality seems to be an important quality for different backends to make the choice of backends clearer to the user.
Since GR is the favorite Plots.jl backend, it would also make sense to start with GR as a reference implementation.
It's less orthogonal and I'm not as familiar with the API, though.
But if @jheinen is on board and willing to help me out, this could also be a great start!
cc: @daschw @mkborregaard @piever @ChrisRackauckas @Evizero @ViralBShah
The text was updated successfully, but these errors were encountered: