Live data from Hacker News

Plotnine

plotnine.org

31–40 of 83 posts

Re: Plotnine

#31
post #5

`from plotnine import *` ... I love the idea of a new python plotting library, but why is this anti-pattern so common with plotting libs?

While it’s generally considered to be bad practice to import everything into the global namespace, I think it’s fine to do this in an ad-hoc environment such as a notebook as it makes using the many functions plotnine provides more convenient. An additional advantage is that the resulting code more closely resembles the original ggplot2 code. Alternatively, it’s quite common to `import plotnine as p9` and prefix ever…

To each his own. Some drawbacks here are that it means that if you want to copy the code in, you have to add all the “p9”s. And, if you want to make a more complicated demo, with maybe a second import, you now have multiple conventions in your demo codebase.

Re: Plotnine

#32
post #5

`from plotnine import *` ... I love the idea of a new python plotting library, but why is this anti-pattern so common with plotting libs?

Because most of the time this will be used is not part of a software development project but rather producing publication plots in a script or plots in a notebook. Not what you would want to do when incorporating it into a web app.

Even in a notebook it's a pain... import plotnine as p9 would be nicer.

Re: Plotnine

#33

Earlier quoted context omitted.

It is! And that's kinda the point. Like others mention, this is inspired by ggplot2, a Grammar of Graphics library. The whole idea is graphics are composed by adding "layers", not like layers on a canvas, but like pouring paint into a pot, then the library understands the content and paints it to the canvas. Layers might be pure data, geometry (lines, points, ...), annotations, styles, axis, etc. When you get familia…

How `plot(.. + ggsize(700, 300) + ..)` is superior to a keyword parameter `plot(.. , size = (700, 300), ..)`?

Because, in the latter case, you have to declare a function argument for /every possible option/ that you want your graphics API to expose, and you need to do this every time you add a new option.

On the other hand, declaring the options through composition means that the API for "plot" remains static, and adding/removing options can be done trivially without an API change.

Composition (rather than parameters) is also more flexible. Let's say you want to divide your plot into three sub-plots, two of which are 200x200, and another which is 200x400. How do you express this as a keyword parameter? In composition, you could do something like:

plot( ggsubplot(ggvsplit(ggsize(200,400), gghsplit(ggsize(200,200), ggsize(200,200)))) )

Re: Plotnine

#34
post #14

If you already use plotnine, or if this has piqued your interest, the next release (v0.16.0) will bring nice capabilities. You can get a sneak peek by installing the pre-release: pip install --pre plotnine Details here: https://github.com/has2k1/plotnine/issues/1031 Disclaimer: I'm the author.

Love your work on this, thanks for bringing the ggplot syntax to Python!

Re: Plotnine

#36
post #5

`from plotnine import *` ... I love the idea of a new python plotting library, but why is this anti-pattern so common with plotting libs?

While it’s generally considered to be bad practice to import everything into the global namespace, I think it’s fine to do this in an ad-hoc environment such as a notebook as it makes using the many functions plotnine provides more convenient. An additional advantage is that the resulting code more closely resembles the original ggplot2 code. Alternatively, it’s quite common to `import plotnine as p9` and prefix ever…

The issue I find with this pattern in docs/tutorials is that the prefix makes it very obvious which functions are from this library.

It's particularly worthwhile when looking at the bigger examples that might involve another library, or stdlib functions/libs I haven't dealt with before

Re: Plotnine

#37
post #33

Earlier quoted context omitted.

How `plot(.. + ggsize(700, 300) + ..)` is superior to a keyword parameter `plot(.. , size = (700, 300), ..)`?

Because, in the latter case, you have to declare a function argument for /every possible option/ that you want your graphics API to expose, and you need to do this every time you add a new option. On the other hand, declaring the options through composition means that the API for "plot" remains static, and adding/removing options can be done trivially without an API change. Composition (rather than parameters) is als…

And how do you express that as arithmetic?

I can get as far as `plot() / 3` but then no idea how to proceed. I don't think overloading arithmetic is a very good way to express this.

Re: Plotnine

#38

I've always liked the ggplot2 and the Grammar of Graphics approach to plotting so much so that I wrote my own DSL based on it - it is standalone, written in Rust, has WASM bindings (as you can see on the website) and more: https://williamcotton.github.io/algraf It pairs well with a related data translation DSL: https://williamcotton.github.io/pdl And you can see the two working together here: https://williamcotton.gi…

Nifty! What motivated you to create these tools?

Re: Plotnine

#39
post #33

Earlier quoted context omitted.

How `plot(.. + ggsize(700, 300) + ..)` is superior to a keyword parameter `plot(.. , size = (700, 300), ..)`?

Because, in the latter case, you have to declare a function argument for /every possible option/ that you want your graphics API to expose, and you need to do this every time you add a new option. On the other hand, declaring the options through composition means that the API for "plot" remains static, and adding/removing options can be done trivially without an API change. Composition (rather than parameters) is als…

kwargs exists, and is rather more pythonic. Just pass the kwargs dict to a standard formatting function, et voila.

Re: Plotnine

#40

I've always liked the ggplot2 and the Grammar of Graphics approach to plotting so much so that I wrote my own DSL based on it - it is standalone, written in Rust, has WASM bindings (as you can see on the website) and more: https://williamcotton.github.io/algraf It pairs well with a related data translation DSL: https://williamcotton.github.io/pdl And you can see the two working together here: https://williamcotton.gi…

Nifty! What motivated you to create these tools?

I really like to build things that build other things!
Post reply on HN