Gael Lorieul
Gael Lorieul

Reputation: 3246

What is SubplotZero? (documentation lacking)

My question

I would like to know what matplotlib's SubplotZero() function does, knowing that it is not referenced in matplotlib's documentation, but is used in at least three examples of the matplotlib website (here for instance). Also, since it is not present in the documentation is it recommended and safe to use? Or is there a risk it might be removed in future versions of matplotlib?


The context

I want to make a plot with matplotlib that displays the "zero" axis. Examples of such plots are shown in matplotlib's examples page. This is done with

ax.axis["xzero"].set_visible(True)

However, writing

ax = plt.gca()
ax.axis["xzero"].set_visible(True)

yields error

ax.axis["xzero"].set_visible(True)
TypeError: 'method' object is not subscriptable

Instead, as was shown in the examples, one is supposed to write (Note: actually there is another way to achieve the same result: see @ImportanceOfBeingErnest's answer)

from mpl_toolkits.axisartist.axislines import SubplotZero
fig = plt.figure()
ax = SubplotZero(fig, 1, 1, 1)
fig.add_subplot(ax)
ax.axis["xzero"].set_visible(True)

which indeed works. However, I was curious to understand what the SubplotZero() function did, and why it existed in the first place (after all why is it needed at all?). So I went to look in the documentation and realized it was not part of it!

Does someone know the answers to those questions?

Upvotes: 4

Views: 1998

Answers (1)

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339745

Wow, so there are three questions here.

Where is the SubplotZero() documentation?

It's currently not documented, since it's an AxesZero, which is augmented to the subplot status via

SubplotZero = matplotlib.axes.subplot_class_factory(AxesZero)

AxesZero is also not documented, but at least appears in the documentation. In general, the complete mpl_toolkits.axisartist is very poorly documented and is missing in the current documentation completely. But one may refer either to an older version or the current devdocs.

It should not be removed in future versions.

What is the reason for the TypeError?

The error TypeError: 'method' object is not subscriptable tells you that a method cannot be indexed.

This happens here as the axis of a SubplotZero, which is a mpl_toolkits.axisartist.axislines.AxesZero, is completely different from the "usual" matplotlib.axes.Axes. The former provides its individual axes as part of a dictionary which can be accessed as ax.axis["xzero"]. The latter is a method, which needs to be called and does some modifications on the axes, e.g. ax.axis("off") turns the axes off. It is indeed quite unfortunate that they both have an attribute axis, refering to completely different things in the end.

How to create an axis at zero position?

While the mpl_toolkits.axisartist module provides this functionality as shown in the quoted example, the use use of this module is admittedly (due the missing/incomplete documentation) rather cumbersome.

An alternative is to use usual matplotlib.axes.Axes. To position a spine at zero position one could refer to the Spine placement demo.

To recreate the linked example with the xaxis spine at zero y position, one would e.g. do

ax.spines['bottom'].set_position(('data', 0))

using an ordinary matplotlib.axes.Axes instance ax.

Complete example:

import numpy as np
import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.set_title('x axis spine at zero data coordinate')
x = np.arange(0, 2*np.pi, 0.01)
ax.plot(x, np.sin(x))
ax.set_xlabel("Axes zero")

ax.spines['bottom'].set_position(('data', 0))
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)

plt.show()

enter image description here

Upvotes: 3

Related Questions