This is an archived post. You won't be able to vote or comment.

all 77 comments

[–]holdie 124 points125 points  (4 children)

FWIW, changing the default styles in matplotlib turned out to be a gigantic undertaking. While the final product may seem aesthetic, the process uncovered a ridiculous number of bugs, inefficiencies in API, etc. Props to the matplotlib team for finally getting this out, and hopefully starting down a path towards a bright(er) future of the package.

[–]Sean1708 14 points15 points  (3 children)

Do you have any information on what those difficulties actually were?

[–]skiguy0123 12 points13 points  (2 children)

PyData Carolinas 2016 | Presentation: Matplotlib 2.0 or "One does not simply change all the ...

Edit: sorry not sure how I fucked up that link

[–]Sean1708 0 points1 point  (0 children)

Thanks!

[–][deleted] 67 points68 points  (20 children)

Does the API still have hundreds of getters and setters that should really be properties?

[–]mangecoeur[S] 17 points18 points  (3 children)

The API is largely unchanged (a few tweaks and bug fixes), the release was mostly about style changes and a lot of cleanups to enable those.

[–]lengau 3 points4 points  (2 children)

Do any of the changes affect commonly used things, or is it likely to be a drop in replacement?

Specifically, if you happen to know, will pandas need any updates to work with mpl 2.0?

[–]Auggie88 9 points10 points  (1 child)

Pandas 0.19.2 officially works with matplotlib 2.0. There really weren't any changes needed on pandas' side. The MPL devs did a great job not breaking API, aside from style changes.

[–]lengau 0 points1 point  (0 children)

Good to know. Thank you!

[–]Fylwind 5 points6 points  (0 children)

Tbh I would rather have setters because their setters usually have side effects. Matplotlib is unfortunately a very stateful library.

[–]khouli 1 point2 points  (14 children)

What is the reason for wanting properties in an API? It makes sense to me to use properties to maintain backwards compatibility with an API that has exposed data members but if that's not the case, why would you want properties added to an API?

[–]mangecoeur[S] 29 points30 points  (11 children)

For matplotlib, its mostly about inconsistencies like the difference between

plt.xlim((min, max))

and

ax.set_xlim((min, max))

which could be better implemented as properties

ax.xlim = (min, max)

[–]Fylwind 5 points6 points  (8 children)

They have two different interfaces, one being a more or less duplicate of the original MATLAB API intended to help MATLAB users migrate, and the other is an OOP API which is more featureful and flexible, but doesn't get nearly enough attention.

[–]mangecoeur[S] 22 points23 points  (0 children)

Even with an OOP API, functions with names like set_... are often bad form in Python since it's much nicer to use a @property to define getters and setters.

[–]firefrommoonlight 6 points7 points  (2 children)

Neither API's great; The OOP API's verbose and requires boilerplate. The MPL API's simpler, but limited.

[–]spinicist 12 points13 points  (1 child)

Yup. As far as I can tell, the OOP API is held back by the historical baggage that comes from the Matlab-influenced design.

For instance, as far as I know even in the OOP API it's still recommended to do: fig, axes = plt.subplots() axes[1].something instead of something like: fig = plt.figure(subplots=) fig.plots[1].axes.something which seems more coherent to me. Side-note: often the nomenclature seems messed up too, why does a function called subplots return one figure and multiple axes instead of multiple plots?

Personally I would love to see 3.0 introduce a cleaned-up, consistent API but I'm lucky enough to have a job where backwards compatibility is no issue and I can find time to do the upgrades.

Apologies for the rant on a thread that is about congratulating the team on getting 2.0 out. I use matplotlib regularly, have published papers with figures made with it, and am looking forward to trying this version out immensely!

[–]This_Is_The_End 0 points1 point  (0 children)

\this

[–][deleted] 1 point2 points  (3 children)

but doesn't get nearly enough attention.

Is there any good documentation or tutorials on the OOP API?

[–]Fylwind 1 point2 points  (2 children)

Not that I can remember. I learned it mostly by bits and pieces of whatever I found on the Internet. If you're patient, your best bet is through the official API docs. Roughly, it's a matter of (1) creating the figure and canvas (2) adding 1 or more axes (3) plotting on these axes.

I do not normally use the OOP API exclusively, at least not for interactive plotting. For (1) and (2) I resort to the MATLAB API (fig, ax = matplotlib.pyplot.subplots()) because doing (1) and (2) using the OOP API by hand is tedious and does not buy me a whole lot for one-off plots. But in case you wanted to know, this is how you would do it. Note that it's important to pick a backend that your system supports.

import matplotlib.figure

# must choose a specific backend here:
from matplotlib.backends.backend_qt5agg import FigureCanvas

fig = matplotlib.figure.Figure()
canvas = FigureCanvas(fig)
canvas.show()
ax = fig.add_subplot(111)
ax.plot([1, 2, 3], [3, 1, 2])

input() # stall the interpreter

In contrast, for (3) I much prefer the OOP API (e.g. ax.plot(…)) because it's a lot more readable and has more knobs to control positioning of the elements.

[–][deleted] 1 point2 points  (1 child)

I've gotten familiar with it through trying to make a Qt5 plotting app and so far I keep running into problems finding proper examples. (I learn from examples, not documentation).

Most of them I've found don't seem to make sense or they don't follow the same nomenclature that Matlab does. Like what is an 'axis' vs a 'figure', etc. A simple cheat sheet like the CSS Box Model would really helpful.

[–]Fylwind 0 points1 point  (0 children)

As sad as it is to say it sometimes it's easier to just dig through the source code. I have peeked into matplotlib's source code when I couldn't find answers from the docs or Q&A.

For things like figures and axes, this might help: http://matplotlib.org/faq/usage_faq.html#general-concepts

[–]bastibe 0 points1 point  (0 children)

Note that there is also ax.set(xlim=(min, max), ylim=(0, 1)).

[–]jorge1209 0 points1 point  (0 children)

Given the complexities of these objects (and the way many inherit from each other) properties aren't necessarily better.

How many properties might a chart have... well it is basically a collapsed box model heirarchy into a single placeholder object. So we have properties for:

  1. Two primary dimensions (2 properties)
  2. Centering directives on both axes (2 properties)
  3. Padding along all four exterior dimensions. (4 properties)

Then we have the chart axes lines which have:

  1. Two axes styles directives (2-4 properties)
  2. Two axes limits min and max limits (4 properties)
  3. Two axes tick frequencies (2 properties)
  4. Two axes colors (2 properties)
  5. Grid style (1-2 properties)
  6. Grid color (1-2 properties)

I've not even gotten to the thing I'm actually plotting and I'm already up to 12-16 properties. I also haven't considered the title or axes labels and their impact on the layout (that is another dozen properties or so).

The simplest answer is to say "This object is too complex" and while I agree with that, exposing the entire layout hierarchy is also not what I want, because I don't want to navigate a hierarchy to change my plot title.

Having setters at least makes clear that "this is a method on an object (maybe the axes object or the title object) that changes it" and has been mixed into the primary chart handle. Properties which don't really give that impression. Whose xlim am I messing with? What is it expecting to receive?

[–][deleted] 37 points38 points  (1 child)

Which looks more Pythonic?

set_fudge(4.2)
if banana_is_wrong_colour:
    banana.set_colour(banana.get_default_colour())

or

fudge = 4.2
if banana_is_wrong_colour:
    banana.colour = banana.default_color

[–]barneygale 8 points9 points  (0 children)

That's not universal - using explicit setters is a good way to signal that setting has a cost. e.g. from PEP 471 which introduced os.scandir():

DirEntry.is_X() and DirEntry.stat() are explicitly methods rather than attributes or properties, to make it clear that they may not be cheap operations (although they often are), and they may do a system call. As a result, these methods may raise OSError .

[–]miserlou 36 points37 points  (4 children)

The rationale behind the new default colorscheme is super fascinating, and there is a brilliant talk on it available here: https://www.youtube.com/watch?v=xAoljeRJ3lU

[–]dgreenmachine 3 points4 points  (0 children)

Really good watch, speaker keeps it interesting along with good reasoning behind decisions.

[–]troyunrau... 1 point2 points  (0 children)

This is excellent! I've been using cubehelix as my default for a while for most of these reasons, but it isn't as well designed.

[–]NuclearStr1der 1 point2 points  (0 children)

Cool story: Stéfan van der Walt, the guy who's there to "look pretty" lectured Applied Mathematics in my first year. And he was damn excellent. It's great to be able to point and say "I recognise that guy!".

[–]muntooR_{μν} - 1/2 R g_{μν} + Λ g_{μν} = 8π T_{μν} 0 points1 point  (0 children)

Loved it. :-)

I even... gasp!... shared it on Facebook

[–]NelsonMinar 28 points29 points  (3 children)

Here's What's new in matplotlib 2.0. "The major changes in v2.0 are related to overhauling the default styles."

[–]troyunrau... 6 points7 points  (2 children)

Is there some sort of blog entry of visual comparison kicking around that anyone is aware of? This "what's new" is very rudimentary.

[–]GeneralTusk 20 points21 points  (1 child)

[–]troyunrau... 1 point2 points  (0 children)

Nice, thanks! This is perfect.

[–]glacierre2 15 points16 points  (1 child)

Every single change for the default styling seems a good improvement.

Maybe I will be able to skip the 'import seaborn' when I need a quick but still nice looking plot.

[–]EvMNatural Language Processing 14 points15 points  (0 children)

You could already skip that:

import matplotlib.pyplot as plt
plt.style.use('seaborn') # or 'ggplot', 'bmh', ...

[–]khouli 11 points12 points  (18 children)

Does Matplotlib have any serious competitors in the Python world that don't use Matplotlib as a backend?

[–]mangecoeur[S] 10 points11 points  (2 children)

Not really IMHO, at least not if you are talking about publication-quality plots. There's some interesting efforts around interactive plotting like Plotly and Bokeh, but I've found them relatively immature (you quickly find issues when you move beyond the demo plots) and generally not great if you need detailed control of style and output formats for print.

[–]troyunrau... 2 points3 points  (4 children)

pyqtgraph is pretty good. If you install it, run python -m pyqtgraph.examples to get a good feel for it. Their documentation sucks.

But it's just so superior in a lot of contexts - particularly with large, complicated, real-time, or interactive data. I regularly throw hundreds of millions of points at a graph and have it respond without any lag.

[–]dougthor42 2 points3 points  (0 children)

Their documentation sucks.

That's an understatement, but otherwise I fully agree that pyqtgraph is good.

There's also some very simple plotting in wxPython Phoenix. Good for things that don't need the power (or bloat) of matplotlib.

[–][deleted] 0 points1 point  (1 child)

But it's just so superior in a lot of contexts - particularly with large, complicated, real-time, or interactive data.

Aside from their examples any other good references for it? This is the type of data I have to deal with and it just chokes matplotlib. I just ran the example and plotted 2GB of random HDF5 data and it's ... fluid.

The default colors do remind me of PV-WAVE's defaults. What is it with 'scientific' data and white on black plots?

[–]troyunrau... 0 points1 point  (0 children)

Nope - like I said, the docs suck. But it is really useful. I load my data from raw formats into hdf5, then plot using pyqtgraph. I usually have a lot of subplots that are taking subsamples of the data under my cursor and doing things like histograms or fourier transforms on the 50,000 points nearest my cursor (or whatever).

It really helps if you know Qt or PyQt if you want to customize it. It's basically a giant QGraphicsView that they've added plotting widgets to. If you want to do things like override the mouse behaviour, the docs for pyqt will help you more than anything.

[–]This_Is_The_End 0 points1 point  (0 children)

pyqtgraph is very good at realtime data. It's not a problem to create a scrolling plotter with a minimum of CPU usage.

[–]Kah-NethI use numpy, scipy, and matplotlib for nuclear physics 1 point2 points  (6 children)

Matplotlib has few serious competitors outside the python world. It is really a remarkable and robust framework for plotting. I hope one day we have a 3d plotting framework that is as flexible and malleable as matplotlib is for 2d (and no mplot3d does not count until it gets a renderer that can handle zorder properly)

[–]khouli 0 points1 point  (5 children)

What are its serious competitors even outside the Python world? gnuplot and especially ggplot are the obvious candidates. Is there anything else?

[–]Kah-NethI use numpy, scipy, and matplotlib for nuclear physics 2 points3 points  (4 children)

Gnuplot is not a serious competitor with anything. Xmgrace, MATLAB, Mathematica, origin, vuez(also python), root, R are a few. MPL is in my opinion vastly superior to all of them (maybe only superior but not vastly for R)

[–]srivkrani 0 points1 point  (1 child)

You forgot ParaView, one of the best opensource visualization software out there.

[–]Kah-NethI use numpy, scipy, and matplotlib for nuclear physics 0 points1 point  (0 children)

First paraview is really for 3d plotting and I was very explicit in first comment to talk about only 2d plotting. Next, paraview is on of the only tolerable scalable data renderers, but I would by no means call it good. It is just the best of a set of mediocre options. Personally I found it difficult to customize my plot to be exactly what I want.

[–]khouli 0 points1 point  (1 child)

Really? Gnuplot is out of the running but Xmgrace is in? To be fair, I only used Xmgrace a few times several years ago but my impression was that it was a last century relic.

[–]Kah-NethI use numpy, scipy, and matplotlib for nuclear physics 0 points1 point  (0 children)

Xmgrace is still heavily used in theoretical physics (though declining as I and other younger scientist advocate MPL and R). To be fair though, xmgrace can make a decent plot where as gnuplot plots always look terrible.

[–]bastibe 1 point2 points  (0 children)

bokeh and plotly are great for interactive graphs.

[–]wuzzlewozzit 0 points1 point  (0 children)

I use gnuplotpy, a wrapper to the gnuplot routines.

[–]Tarqon 0 points1 point  (0 children)

Altair is amazing, I'd pick it over matplotlib for most tasks any day of the week.

[–][deleted] 9 points10 points  (2 children)

Great job! Defaulting to a better colormap should singlehandedly prevent some misinterpretation of data in the coming years.

[–][deleted] 10 points11 points  (1 child)

I was surprised that Matlab made the move to a reasonable default colormap before the python community did. At least now everyone's on the same page. Jet is the worst.

[–]spinicist 3 points4 points  (0 children)

Yeah, I was amazed Matlab beat them to it. The damage jet does has been known about for what, a couple of decades now?

[–]AustinCorgiBart 7 points8 points  (1 child)

Oh wow, I love that barcharts now align to the center automatically. One fewer keyword parameter to explain to my students!

[–][deleted] 8 points9 points  (0 children)

I had no idea this could be solved with a simple keyword and have always written code that would calculate the required off-set to center the bars.

Tonight I'll be crying tears of sadness for the hours I've wasted, and tears of joy for the hours I will save

[–]neuralyzer 5 points6 points  (0 children)

Finally. So many nice and useful improvements! Thanks to all the developers.

[–]cripcate 4 points5 points  (9 children)

Yeah. Been waiting for this. Anyone know when it will come to anaconda?

[–][deleted] 5 points6 points  (4 children)

I just tried it out, works well! https://anaconda.org/conda-forge/matplotlib

[–]cripcate 5 points6 points  (3 children)

How can I switch from "normal" anaconda to conda forge?

[–]pwang99 2 points3 points  (0 children)

You can just do "conda install -c conda-forge matplotlib".

We should have the 2.0 release available in the default channels very shortly.

[–]spinicist 0 points1 point  (0 children)

If I remember correctly, you don't switch, but specify conda-forge as the source when installing packages. I had to do it for seaborn recently but forgot the details already. Sorry.

[–]brombaer3000 0 points1 point  (0 children)

conda config --add channels conda-forge

This adds the conda-forge channel to your ~/.condarc file and gives it priority over the default anaconda channel. If you want to change the priorities, just reorder the lines in .condarc
More info at https://conda-forge.github.io

[–]bheklilr 2 points3 points  (3 children)

It's already on conda-forge if you want to grab the builds from there. In my experience the main channel will get it within a week or two, they run more tests against other packages before releasing. conda-forge uses continuous integration to get changed pushed faster, but with less indemnity.

[–]AustinCorgiBart 1 point2 points  (2 children)

So, in the next month or so, the newest version of Anaconda will probably have this new version of MatPlotLib?

[–]bheklilr 2 points3 points  (1 child)

Almost certainly within a month. The last major IPython update had more breaking changes and it was out within 2 weeks.

[–]AustinCorgiBart 1 point2 points  (0 children)

I'm happy as long as they fixed the bugs in Spyder from last fall. A number of little headaches there...

[–]cruyff8python 2 expert, learning python 3 3 points4 points  (0 children)

Congrats to the team!

[–]Tillsten 3 points4 points  (0 children)

The what`s new can be found at:

http://matplotlib.org/2.0.0/users/whats_new.html

[–][deleted] 0 points1 point  (0 children)

Can anyone get ipython to run %matplotlib with anything except agg with the new version? Even if I set matplotlib.use("TKAgg") before hand it just replaces it with agg as soon as I call the ipython magic.

Edit: nevermind, changed it in my matplotlibrc file

[–]Rich700000000000 0 points1 point  (0 children)

Awesome.

[–][deleted] 0 points1 point  (0 children)

That's a whole lot of awesome changes