30

Say I have a matplotlib axes called ax, and I want to set several of its properties. Currently, I do it like this:

ax.set_yscale('log')
ax.set_xlim([0,10])
ax.set_xlabel('some label')

But it gets tedious after a while. Then I ran into this method:

ax.set(yscale='log', xlim=[0,10], xlabel='some label')

Much more concise, but it seems a bit undocumented. I mean all the documentation says is "A tkstyle set command, pass kwargs to set properties".

What is the preferred or idiomatic way? Is the set method api stable?

jarondl
  • 1,593
  • 4
  • 18
  • 27

4 Answers4

18

Pyplot tutorial appears to recommend ax.set_xxx() functions, but also mentions .setp(xxx=).

On the other hand, .set(xxx=) function is not used and .setp(xxx=), while documented, is not used in any examples (Pyplot API).

I understand it that matplotlib supports both imperative programming style and matlab-like style. Reason being the target user bases -- those already familiar with Python and those who used Matlab before.

I conclude that matplotlib recommended api is .set_xxx().

A quick check through the gallery confirms this.

Edit: it appears there are examples of both in the gallery now.

Similar duality exists for keyword arguments to plot functions, except that imperative API is not that obvious.

Dima Tisnek
  • 11,241
  • 4
  • 68
  • 120
  • 1
    Answer covers apparent matplotlib api. I would prefer both options available and documented. – Dima Tisnek Dec 03 '12 at 13:03
  • Great answer, thanks. Not sure if `setp(xxx=y)` or `set_xxx(y)` is more "pythonic", but both are not exactly object-oriented approaches; the latter will navigate up and down and across the crazy hierarchy of matplotlib class instances, and sometimes silently set class properties or substitute a simple/numeric input with new class instances (e.g. in `set_xticklabels(y)` passing `y` to `ticker.FixedFormatter(y)`). Both are only object-oriented-ish. – Luke Davis Apr 27 '17 at 17:56
  • [Times change](https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.axes.Axes.set.html). – Alan May 14 '20 at 22:30
  • Thanks @Alan can you maybe summarise what the recommendation is now? – Dima Tisnek May 15 '20 at 02:52
  • 1
    IMO, since the docs now include examples of both, you should use what you like/need. I usually use `set` when I have multiple properties to set on a single axes instance. – Alan May 15 '20 at 22:55
9

As a super-late followup to this question:

ax.set_xlim(4) and ax.set(xlim=4) are ultimately the same thing, so do what you like. ax.set(kwarg=foo) calls ax.set_kwarg(foo) via some string manipulation, as you can see if you look at the source. The various setter functions are mostly one-liners, as well, but exist to allow for the introspective setp to work.

Excalabur
  • 304
  • 3
  • 9
3

I usually use the pyplot (interactive) interface for matplotlib, which exposes the setp function (which I use very often).

matplotlib supports the use of setp() (“set property”) and getp() to set and get object properties, as well as to do introspection on the object.

Which lets you do things just like your set function above, only you pass the object to set as a parameter:

>>> x = arange(0,1.0,0.01)
>>> y1 = sin(2*pi*x)
>>> y2 = sin(4*pi*x)
>>> lines = plot(x, y1, x, y2)
>>> setp(lines, linewidth=2, color='r')

I'm guessing the setp function actually calls the passed object's set function which works to locate and set the kwargs.

So my thoughts are, that despite the lack of documentation the object's set method is the idiomatic approach for setting multiple parameters via kwargs instead of line by line.

My 2 cents.

Chris Zeh
  • 924
  • 8
  • 23
0

I have similar issues with matplotlib backend and so I just came across this post. I was hoping matplotlib would allow for the use of dictionary control for the properties in a plot. Using the suggestion by @Chris Zeh you could:

f = {'xlabel': 'x1', 'ylabel': 'x2'}
[setp(ax, formati, formatj) for formati, formatj in f.items()]

which solves my problems. Hope this helps.

cvanelteren
  • 1,633
  • 9
  • 16