gboffi
gboffi

Reputation: 25093

Passing optional arguments to, e.g., ax.set(ylabel=...)

Having read this Q&A I know how I can specify optional arguments to a y label object, using either the pyplot namespace

plt.ylabel('y', rotation='horizontal', ha='right')

or the object oriented one

ax.set_ylabel(...)

but I don't know how I could possibly use the convenient syntax

ax.set(ylabel=???)

and still be able to specify additional parameters.

Upvotes: 4

Views: 797

Answers (2)

William Miller
William Miller

Reputation: 10328

The Axes class doesn't have an override for the set() method, so matplotlib.axes.Axes.set() is the same as matplotlib.artist.Artist.set() which calls matplotlib.artist.Artist.update() with the the specified keyword argument list (props). update() looks like this:

def update(self, props):
    ret = []
    with cbook._setattr_cm(self, eventson=False):
        for k, v in props.items():
            # ...
            if k == "axes":
                ret.append(setattr(self, k, v))
            else:
                func = getattr(self, f"set_{k}", None)
                if not callable(func):
                    raise AttributeError(f"{type(self).__name__!r} object "
                                         f"has no property {k!r}")
                ret.append(func(v))
    # ....
    return ret

This goes through the props dict and checks if a setter method of self (in the case of matplotlib.axes.Axes.set() the Axes instance) exists for each key, if it does then it calls it with the associated value, if not it raises an AttributeError. This means that you can't use the set() method to change attributes for which there is no defined setter method (the one exception is that you can pass the axes argument to reset the axes).

Since matplotlib.axes.Axes does not have a setter for the label rotations and alignments, you can't use ax.set() to mutate these. What you can do is call .set() on the text instance instead, i.e.

import matplotlib.pyplot as plt

fig, ax = plt.subplots(1)
ylab = ax.set_ylabel("y-label")
ylab.set(rotation="horizontal", ha="right")

I think this is the closest to your desired usage that is possible with .set().

Upvotes: 1

Idea O.
Idea O.

Reputation: 480

A simple example of its usage:

import matplotlib
import matplotlib.pyplot as plt
import numpy as np

# Data for plotting
t = np.arange(0.0, 2.0, 0.01)
s = 1 + np.sin(2 * np.pi * t)

fig, ax = plt.subplots()
ax.plot(t, s)

ax.set(xlabel='time (s)', ylabel='voltage (mV)',
       title='About as simple as it gets, folks')
ax.grid()

fig.savefig("test.png")
plt.show()

Beware that the options available to the other two approach you mention will not be available when using ax.set(), because this is only "a property batch setter", hence only properties of Axes will be exposed.

Upvotes: 2

Related Questions