Thanks for all the suggestions---the Require package is probably what I go for now. Looking at Sims.jl, it is probably not the most fun implementing the various plots I want to make in the many plotting environments available in Julia, the least of which are to get all those environments working locally, and writing tests that are both useful and manage to pass Travis...
I totally understand the problems of standardizing a plotting API, and I suppose every plotting package author sincerely believes her package is closest to the one and only true ideal general multipurpose API---at least, I would. I've used many different plotting environments in the past (and of course, a long time ago, written some for my own use in different languages and targeted at different output hardware), but I would find it hard to give objective arguments as to what interface is better---so much depends on what you're used to, and what your needs are. I think Matt's approach looks promising. I can imagine different plotting packages might have completely different approaches to how a plot should be built up, what the order of things are, etc, so it won't be easy to do. Cheers, ---david On Friday, January 23, 2015 at 2:19:28 AM UTC+1, tshort wrote: > > Sims.jl uses the Requires.jl approach that Matt mentioned. There are a few > helper plotting methods that are optional depending on what packages the > user loads: > > https://github.com/tshort/Sims.jl/blob/master/src/utils.jl#L158-L181 > > https://tshort.github.io/Sims.jl/plotting/ > > > > On Thu, Jan 22, 2015 at 3:36 PM, Matt Bauman <[email protected] > <javascript:>> wrote: > >> I've thought some about this in the past, too. Coming from Matlab, I've >> imagined a Matlab-esque Base.Plots module that has just a handful of >> definitions, mirroring the IO system: >> >> abstract AbstractPlot >> immutable NoPlots <: AbstractPlot end >> STDPLOT = NoPlots() # When a plotting package loads, it assigns its own >> AbstractPlot object to STDPLOT >> >> line(args...) = line(STDPLOT, args...) >> line(p::AbstractPlot, ys::AbstractArray) = line(p, 1:size(ys,1), ys) >> # Then each plotting package would specialize on the following method: >> line(::NoPlots, xs, ys) = error("Plotting requires a plotting package to >> be installed. Here, try one of these: …") >> >> # … and so on for just a handful of very common (and specific!) names … >> scatter() … >> bar() … >> surface() … >> >> Of course, doing anything more complicated would require delving into >> documentation and using a more package-specific function. But users could >> easily start from the source for these simple prototypes and grow from >> there. Sure, this will be heretical for some plotting packages, but I >> think there's value here, especially for quick and dirty exploratory data >> analysis. >> >> The plot function is tougher — there's not really a meaning to it beyond >> "show this thing graphically," and packages use keywords or other arguments >> to determine the kind of plot. I could see it being useful in cases like >> yours, though, where you want to define a plotting routine for a your own >> ROC object type. You would simply define `plot(p::AbstractPlot, t:: >> ROCType)` and then use the above primitives. The trouble is, as a >> package author, you'll want to add fancier features like labels, legends, >> colors, titles, bounds, error-bars, shaded regions, transforms, etc…. and >> now we're marching down that crazy never-ending path Daniel fears. >> >> So: yes, it's possible. Is it useful? I'm not so sure. I think no >> matter what you're going to have to learn a specific plotting API, and as a >> package author I think you're better off picking one to support well and >> extending its functions directly. Maybe some cavalier users will come by >> and add support for others they like with lazy loading through Requires.jl. >> :) >> >> Matt >> >> On Thursday, January 22, 2015 at 1:03:44 PM UTC-5, Simon Danisch wrote: >>> >>> The reference does seem to fit here, as a general plotting language >>> seems to be awfully complicated. >>> By the way, I totally forgot to mention, that I want to turn GLPlot more >>> into a meta package, offering different plotting interfaces, since I'm >>> generalizing more and more of the render code and a lot of people prefer >>> different interfaces to the same functionality. >>> So it might become a lightweight package, which actually doesn't contain >>> render code and only defines interfaces. >>> If someone has any API that he wants to implement, GLPlot might become >>> the go to package. If this happens, I should rename it though ;) >>> >>> >>> Am Donnerstag, 22. Januar 2015 16:42:37 UTC+1 schrieb David van Leeuwen: >>>> >>>> Hello, >>>> >>>> I've just read up on most recent conversations mentioning plotting, >>>> after I went through a similar install-and-try-out cycle for the various >>>> plotting packages. >>>> >>>> I am busy with a package named ROC <https://github.com/davidavdav/ROC> >>>> (Receiver >>>> Operating Characteristic). It is mostly about decision cost functions and >>>> efficiently computing ROC statistics, but there is also some support for >>>> making various plots related to the ROC. >>>> >>>> I do not want to decide for a potential user of this package which >>>> plotting package she should use. So it would be nice if there would be an >>>> abstract plotting API (I suppose this does not exist yet). >>>> >>>> Supposing that it is possible to make an API that includes some common >>>> plotting primitives, and that makes a runtime selection based on >>>> `isdefined(plottingpackagename)`, >>>> how would you >>>> - overload a function, typically `plot()`, when at module-include time >>>> it is not yet known which plotting package the user wants >>>> - specify the dependence of this package to any one of the available >>>> plotting packages. >>>> >>>> Thoughts? >>>> >>>> Thanks, >>>> >>>> ---david >>>> >>> >
