Search code examples
pythonmatplotlibmultiple-axes

Matplotlib: Simplest possible example for 2 x 1 - grid of plots fails with "cannot create weak reference to bool"


I'm trying to do the simplest possible 1-row, 2-column multi-ax-plot with matplotlib, actually taken from the examples in the documentation:

from matplotlib import pyplot as plt
fig, (ax1, ax2) = plt.subplot(nrows=1, ncols=2, sharey=True)


    ---------------------------------------------------------------------------

    TypeError                                 Traceback (most recent call last)

    <ipython-input-9-4bc4f1ccd8e8> in <module>
          1 from matplotlib import pyplot as plt
    ----> 2 fig, (ax1, ax2) = plt.subplot(nrows=1, ncols=2, sharey=True)


    ~/.virtualenvs/tcpsp/lib/python3.7/site-packages/matplotlib/pyplot.py in subplot(*args, **kwargs)
       1082 
       1083     fig = gcf()
    -> 1084     a = fig.add_subplot(*args, **kwargs)
       1085     bbox = a.bbox
       1086     byebye = []


    ~/.virtualenvs/tcpsp/lib/python3.7/site-packages/matplotlib/figure.py in add_subplot(self, *args, **kwargs)
       1365                     self._axstack.remove(ax)
       1366 
    -> 1367             a = subplot_class_factory(projection_class)(self, *args, **kwargs)
       1368         self._axstack.add(key, a)
       1369         self.sca(a)


    ~/.virtualenvs/tcpsp/lib/python3.7/site-packages/matplotlib/axes/_subplots.py in __init__(self, fig, *args, **kwargs)
         68 
         69         # _axes_class is set in the subplot_class_factory
    ---> 70         self._axes_class.__init__(self, fig, self.figbox, **kwargs)
         71         # add a layout box to this, for both the full axis, and the poss
         72         # of the axis.  We need both because the axes may become smaller


    ~/.virtualenvs/tcpsp/lib/python3.7/site-packages/matplotlib/axes/_base.py in __init__(self, fig, rect, facecolor, frameon, sharex, sharey, label, xscale, yscale, **kwargs)
        471             self._shared_x_axes.join(self, sharex)
        472         if sharey is not None:
    --> 473             self._shared_y_axes.join(self, sharey)
        474         self.set_label(label)
        475         self.set_figure(fig)


    ~/.virtualenvs/tcpsp/lib/python3.7/site-packages/matplotlib/cbook/__init__.py in join(self, a, *args)
        923 
        924         for arg in args:
    --> 925             set_b = mapping.get(weakref.ref(arg), [weakref.ref(arg)])
        926             if set_b is not set_a:
        927                 if len(set_b) > len(set_a):


    TypeError: cannot create weak reference to 'bool' object



    <Figure size 432x288 with 0 Axes>



I honestly have no clue why it tries to create a weak reference to a bool.

I'm using fairly recent versions of matplotlib and Python:

import sys
print(sys.version)
    3.7.0 (default, Sep 12 2018, 18:30:08) 
    [GCC 8.0.1 20180414 (experimental) [trunk revision 259383]]
import matplotlib
matplotlib.__version__

    '3.0.2'

Am I right to assume that the example from the documentation should work? Is this a Matplotlib bug or have I done something wrong?


Solution

  • First off, use plt.subplots()

    It might be easier to not unpack your ax subplots variable until you want to customize each plot individually.

    Usually how i'll do it is:

    
    fig, ax = plt.subplots(1, 2, dpi=175)
    
    quadrants = 0, 1
    

    so if I need to apply anything globally I can do:

    for quad in quadrants:
        ax[quad]. (whatever)
    

    and then individually:

    ax[0].plot(...)
    

    This also scales pretty well, such that if I was working with instead a 2x2 matrix of plots (like I am now), the difference is simply:

    fig, ax = plt.subplots(2, 2, dpi=175)
    
    quadrants = (0,0),(0,1),(1,0),(1,1)