Skip to content
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

Hook into Plots.jl and/or Makie.jl #108

Open
sethaxen opened this issue Feb 4, 2021 · 11 comments
Open

Hook into Plots.jl and/or Makie.jl #108

sethaxen opened this issue Feb 4, 2021 · 11 comments
Labels
enhancement New feature or request

Comments

@sethaxen
Copy link
Member

sethaxen commented Feb 4, 2021

Currently ArviZ.jl only supports ArviZ's matplotlib backend (using PyPlot.jl) and partially supports its Bokeh backend. ArviZ.jl should hook into Plots.jl for several reasons:

  • better interop with Julia packages. The plots objects would be native Julia objects and could be easily modified or included in existing figures using the Plots.jl API.
  • instant access to a multitude of backends, including the interactive PlotlyJS.jl backend, publication-quality plots with PGFPlotsX.jl, plots in the REPL with UnicodePlots.jl, and, of course, PyPlot.jl.

Makie.jl is a newer package that offers highly performant, interactive plots. Both packages use a recipe system for designing new plots. Plots.jl recipes can be consumed by Makie.jl, but the interactivity/reactivity is lost.

There are a few ways we could go about doing this.

  1. Add a new "backend" to ArviZ (the Python package) that, instead of plotting, just returns all data necessary to create a plot. We would then define recipes that always call the Python plotting function with this backend and then implement the same plot in the Plots API.
  2. Reimplement the plots from scratch, calling the necessary internal functions in the ArviZ Python package or Julia equivalents to perform the necessary analyses.

Both of these options have a significant drawback: requiring more maintenance time for this package.

The first option requires a lot of work upfront on the Python side, but very little on the Julia side. However, it will ultimately require more work to maintain on the Julia side, as changes to Python ArviZ can change the data returned and potentially break the plot for Julia. And unlike with Julia package dependencies, we cannot use version bounds to enforce that only mutually compatible versions of the Julia and Python packages are installed. This has made keeping the packages in sync challenging.

The second option requires more work upfront but will ultimately be easier to maintain. However, as new plotting options are added to ArviZ, work would be needed to support them over here, and gradually the two packages could become out-of-sync in the features they support.

For now I think the way forward is to experiment with the second option for very simple plots and see if the same component recipes can be trivially combined to construct the more elaborate plots. I'm interested in any alternative suggestions though.

@ColCarroll
Copy link
Member

Sounds great! Maybe worth updating https://github.com/arviz-devs/arviz/wiki/ArviZ-2021-roadmap to keep track of your thoughts?

I like the idea of arviz's non-plot code providing a sufficient API to (easily) reproduce the plots: seems like that could enforce modularity and separation of concerns!

@ahartikainen
Copy link

At this step, should we clean the plotting data -> back-end interface? Currently they are more or less hacked together?

@sethaxen
Copy link
Member Author

sethaxen commented Feb 7, 2021

Sounds great! Maybe worth updating https://github.com/arviz-devs/arviz/wiki/ArviZ-2021-roadmap to keep track of your thoughts?

Good idea! Will do. Done!

I like the idea of arviz's non-plot code providing a sufficient API to (easily) reproduce the plots: seems like that could enforce modularity and separation of concerns!

Yes I agree this will be a nice stress test of the modularity of arviz. I'd prefer to avoid dipping into non-API functions if possible and instead reproduce functionality here to avoid annoying breakage and/or difficult maintenance. It's actually preferable to me to have pure Julia implementations of functions if simple to do so here or use Julia equivalents if they exist than to access non-API functions, since that will be more difficult to maintain. An example of this is kde.

At this step, should we clean the plotting data -> back-end interface? Currently they are more or less hacked together?

After experimenting with this over the last few days, I don't think it will make much of a difference for these features. It would make it a bit easier for me to follow what a plot is doing (i.e. separating computation of statistics from how its plotting), but I'd be essentially duplicating the sequence of computations here.

@sethaxen
Copy link
Member Author

sethaxen commented Feb 9, 2021

Work on ArviZ/Plots integration has begun at https://github.com/arviz-devs/ArviZPlots.jl.

@treigerm
Copy link

Hey just want to leave a comment saying that I'm really looking forward to this! In the past I've run into some issues with having the right Python libraries installed for plotting in my Julia environment. Having the plotting done all on the Julia side would simplify things a lot.

@sethaxen
Copy link
Member Author

Thanks, @treigerm, I'm looking forward to it too! The idea for now is to still handle all analyses on the Python side and just implement the necessary Plots.jl recipes to handle the plotting itself in Julia. So you'd still need e.g. matplotlib installed, but it wouldn't be used for the plots unless you triggered the pyplot backend in Plots.

What kind of issues have you had getting the Python libraries installed? It would be nice to know of any reproducible issues blocking usage of ArviZ.

@treigerm
Copy link

I was just trying to reproduce the issue I had and now it has disappeared. I think potentially it had something to do with which conda environment I had activated. It's not a major issue for me right so I don't have time to investigate it further but I will open an issue once I encounter it again.

@ParadaCarleton
Copy link

I'm not sure how much work has been done on this already, but I think we might want to consider whether we want to use Plots.jl or a package that has more in common with ggplot2, such as VegaLite or Gadfly. A ggplot2-like package would let you almost copy/paste code directly from Bayesplot, which has a lot of functionality already. Another advantage is that a lot of people are familiar with ggplot2; people who are used to Python can already use Arviz.jl together with PyPlot, but anyone used to R is going to have a lot of trouble switching to doing their Bayesian stats in Julia.

@sethaxen
Copy link
Member Author

sethaxen commented Aug 9, 2023

The current plan is to implement 2 packages: ArviZPlots.jl and ArviZMakie.jl. These packages should probably share a repo (this repo?) so that it's easier to keep their APIs similar. It's probably not reasonable to keep the APIs identical, as style keywords should probably follow the conventions of the corresponding plotting package, but everything else about the interfaces should be as close as possible.

@sethaxen sethaxen added the enhancement New feature or request label Aug 9, 2023
@alecloudenback
Copy link

@sethaxen I'd be willing to help out with this, starting with Makie. If there's no prior work on this I could just start working on this, generally following the pattern in the Python versions.

After talking with the Makie devs re: a PR to MCMCChains, instead of a new ArviZMakie package, would the pattern currently shown in that PR using extensions work here?

@sethaxen
Copy link
Member Author

sethaxen commented Apr 1, 2024

Hi @alecloudenback, thanks for the interest! Help would certainly be appreciated! Currently we have an open GSoC project to work on this, and we're expecting at least one application, but there are a lot of plots to implement and plenty of ways to contribute. Perhaps we can touch base after I see what applications we receive.

After talking with the Makie devs re: a PR to MCMCChains, instead of a new ArviZMakie package, would the pattern currently shown in that PR using extensions work here?

My current thinking on this is that it makes more sense to have a stand-alone package for several reasons, including:

  • We would ultimately like to support both Makie and Plots. Defining functions here that are then overloaded by an extension would cause clashes if both Makie and Plots are in scope, unless if we designed a mechanism for switching backends. That's challenging to get right when using recipes. Without recipes, perhaps it's possible, but this decreases usability of the code.
  • My current thinking is that most plots could be separated into 1) performing an analysis that produces a new Dataset 2) reformatting that Dataset into one or more Tables 3) using the Tables interface in AlgebraOfGraphics (or StatsPlots) to construct the plots. For Makie this would require an AlgebraOfGraphics dependency, which doesn't fit the extensions approach well

With an ArviZMakie package, we can focus on just getting the package right. In the future, we could always move the functionality into an extension if that makes more sense.

It's worth pointing out that Python ArviZ is also going through a refactor that separates the plots out into their own package, which also involves splitting some plots into multiple plots: https://github.com/arviz-devs/arviz-plots

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Status: Planned
Development

No branches or pull requests

6 participants