Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the guidelines for using matplotlib's set_array() routine?

The documentation for set_array is very skimpy. What does it do? What range of values can it take? How does it work in conjunction with other color-related routines and data structures?

On the collections docpage it is said to "Set the image array from numpy array A." It is described in the same way in the colormap API. That's all.

I find no mention of set_array() (much less examples) in any of several popular books on matplotlib programming, such as Devert (2014), McGreggor (2015), Root (2015) and Tossi (2009).

Yet, if set_array() is some arcane function that is only needed in rare cases, why does it show up so often both in matplotlib examples and in examples posted on the SciKit Learn website? Seems like a pretty mainstream function, and so it ought to have more mainstream documentation.

For example:

  • Matplotlib docs: Use of set_array() in creation of a multi-colored line
  • Matplotlib docs: Line collection with masked arrays
  • Scikit Learn docs: Visualization of stockmarket structure

Sifting through Stack Overflow posts that mention set_array() I found this one, where a poster states that "set_array() handles mapping an array of data values to RGB", and this one where posters indicate that set_array() must be called in some cases when one is setting up a ScalarMappable object.

I've tried experimenting with the examples I've found on-line, changing the range of values passed in to set_array(), for example, to try to figure out what it is doing. But, at this point, I'm spending way too much time on this one dumb function. Those deeply into color maps have enough context to guess what it does, but I can't afford to take a detour that big, just to understand this one function.

Could someone please offer a quick description and maybe some links?

like image 336
John Strong Avatar asked Apr 28 '18 15:04

John Strong


1 Answers

The set_array method doesn't do much per se. It only defines the content of an array that is internal to the object in which it is defined. See for instance in the source of matplotlib.cm

def set_array(self, A):
    """
    Set the image array from numpy array *A*.

    Parameters
    ----------
    A : ndarray
    """
    self._A = A
    self._update_dict['array'] = True

In the multicolored_line example of the matplotlib documentation, this is used to map colors of a cmap.

Let's take a similar example and create a collection of lines and map the segments to indexed colors in a colormap:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
from matplotlib.colors import ListedColormap, BoundaryNorm

f, axes = plt.subplots(ncols=3)

y = np.arange(0,1,0.1).repeat(2)
x = np.append(y[1:], [1])
segments = np.array(list(zip(x,y))).reshape(-1, 2, 2)

cmap = ListedColormap(['r', 'g', 'b'])
norm = BoundaryNorm([-0.5, 0.5, 1.5, 2.5], cmap.N)

for ax in axes:
    ax.add_collection(LineCollection(segments, cmap=ListedColormap(['r', 'g', 'b']), norm=norm))
    
axes[1].collections[0].set_array(np.array([0,1]))
axes[2].collections[0].set_array(np.array([0,1,2]))

axes[1].set_title('set_array to [0,1]')
axes[2].set_title('set_array to [0,1,2]')

This gives the following output:

mapping cmap using set_array

What is does is to map the segment to the indexed colors defined in the cmap (here 0->'r', 1->'g', 2->'b'). This behaviour is specified in the matpotlib.collections source:

Each Collection can optionally be used as its own `.ScalarMappable` by
passing the *norm* and *cmap* parameters to its constructor. If the
Collection's `.ScalarMappable` matrix ``_A`` has been set (via a call
to `.Collection.set_array`), then at draw time this internal scalar
mappable will be used to set the ``facecolors`` and ``edgecolors``,
ignoring those that were manually passed in.
like image 73
mozway Avatar answered Nov 17 '22 06:11

mozway