I\'m trying to get the data values along a line (like in this hint). That example uses imshow()
, but I\'m currently using pcolormesh()
to plot.
The shape of the array in stored in private attributes, _meshWidth and _meshHeight. Nevertheless, since these attributes are not part of the public API, it would be better to save the shape of the original data than to rely on these if possible.
import matplotlib.pyplot as plt
import numpy as np
D = np.random.uniform(0, 100, size=(5, 5))
fig, ax = plt.subplots()
h, w = D.shape
img = ax.pcolormesh( np.arange(h+1), np.arange(w+1), D)
D2 = img.get_array().reshape(img._meshWidth, img._meshHeight)
assert np.array_equal(D, D2)
Note also that if you wish to recover the original array D
, then the coordinate arrays, np.arange(h+1)
, np.arange(w+1)
must have lengths one bigger than the shape of D
. Otherwise, img.get_array()
returns an array of shape (499, 499)
when D
has shape (500, 500)
.
Yes, it does ravel the inputs:
https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/axes/_axes.py
# convert to one dimensional arrays
C = C.ravel()
X = X.ravel()
Y = Y.ravel()
If you know the desired 2d shape, you can unravel with a simple reshape
call.
If the result should have the same shape as D
use:
img.get_array().reshape(D.shape)
If the size of the raveled C
can change, then this won't work.
If I make a D
array that is (10,20)
, and plot it
img = pyplot.pcolormesh(D)
img._A
is (200,), the array that img.get_array()
returns.
img._meshHeight, img._meshWidth
# 10, 20
So the array can be reshaped with:
img._A.reshape(img._meshHeight, img._meshWidth)
img._coordinates
is a (11,21,2) array, the coordinates in the x and y direction, plus one point. So you could get the C
reshaping information from _coordinates
as well. I don't see any public API method for retrieving these attributes, but that doesn't stop 'serious' Python programmers. In this test case, it generated the coordinates
from the shape of D
.
This Quadmesh
was created with:
coords = np.zeros(((Nx * Ny), 2), dtype=float)
coords[:, 0] = X
coords[:, 1] = Y
collection = QuadMesh(
Nx - 1, Ny - 1, coords, ...)
....
collection.set_array(C)
A search for get_array
in the matplotlib
github repository does not get many hits.
I dug into the pcolor
code a bit. It returns a PolyCollections
img rather than a Quadmesh. It contains the information for drawing a collection of quadrilaterals.
For example in my test case with a 10x20 input, img._paths
is a list of 200 Path
objects
In [486]: img1._paths[0]
Out[486]:
Path(array([[ 0., 0.],
[ 0., 1.],
[ 1., 1.],
[ 1., 0.],
[ 0., 0.],
[ 0., 0.]]), array([ 1, 2, 2, 2, 2, 79], dtype=uint8))
It has five coordinate pairs, the xy
points needed to draw the boundary of the quad, which will have a color value corresponding to C[0]
(in the raveled form).
So all the X
Y
grid information is now coded in these Path
objects. Instead of plotting a mesh it plots 200 colored squares (quads). The PolyCollections
code does not assume that the squares are in any order or even touching each other. The big picture has been replaced with a bunch of independent small pictures.
You might be able reassemble those quads into a mesh, looking for matching vertices, etc. But it would be a lot of work.