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:
set_array()
in creation of a multi-colored line
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?
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:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With