Matplotlib:`pcolormesh.get_array()`返回flattened数组 - 如何获取2D数据?

时间:2016-01-17 15:59:21

标签: python numpy matplotlib

我正在尝试沿着一条线获取数据值(如this hint中所示)。该示例使用imshow(),但我目前正在使用pcolormesh()进行绘制。

我发现从get_array()抓取绘制数据的pcolormesh()函数返回的是我的数据的1-D平坦数组,而不是原始(或截断的)2-D数据

例如:

D = np.genfromtxt(DataFilePath, skip_header=4, delimiter=',', unpack=True)
print( D.shape )
: (500, 500)

...more code...

img = ax[0].pcolormesh( np.arange( len(D[0,:]) ), np.arange(len(D[:,0])), D)

>>> D
: array([[ 42.38,  41.93,  41.92, ...,  41.73,  41.74,  41.51],
       [ 41.88,  42.24,  42.21, ...,  41.88,  41.67,  41.64],
       [ 42.4 ,  41.47,  41.49, ...,  41.92,  42.07,  41.49],
       ..., 
       [ 44.24,  44.14,  44.17, ...,  40.2 ,  40.68,  40.67],
       [ 44.59,  44.24,  44.3 , ...,  40.91,  40.92,  40.95],
       [ 44.2 ,  44.27,  44.27, ...,  40.82,  40.91,  40.94]])
>>> img.get_array()
: array([ 42.38,  41.93,  41.92, ...,  40.85,  40.91,  40.92])

由于我试图在绘图上抓取用户点击,然后使用点击的数据值重新绘制(如在this hint中),我想使用赢得的函数/类无法全局访问原始数据,但可以访问img对象。

我是否知道如何仅使用pcolormesh()(QuadMesh)对象从img获取2D数据?它甚至似乎没有x / y长度/形状值,因此我可以从1-D get_array()重建数据。

谢谢!

2 个答案:

答案 0 :(得分:3)

存储在私有属性_meshWidth and _meshHeight中的数组的形状。然而,由于这些属性不是公共API的一部分,因此保存原始数据的形状比在可能的情况下依赖这些属性更好。

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)

另请注意,如果您希望恢复原始数组D,则坐标数组np.arange(h+1)np.arange(w+1)的长度必须大于D的形状。否则,当img.get_array()具有(499, 499)形状时,D会返回形状(500, 500)的数组。

答案 1 :(得分:2)

是的,它确实对输入进行了调整:

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()

如果您知道所需的2d形状,则可以通过简单的reshape调用解开。

如果结果应与D具有相同的形状,请使用:

img.get_array().reshape(D.shape)

如果raveled C的大小可以改变,那么这将无效。

如果我创建一个D数组(10,20),并将其绘制成

img = pyplot.pcolormesh(D)

img._A是(200,),img.get_array()返回的数组。

img._meshHeight, img._meshWidth
# 10, 20

因此可以使用:

重新整形数组
img._A.reshape(img._meshHeight, img._meshWidth)

img._coordinates是一个(11,21,2)数组,x和y方向的坐标加上一个点。因此,您也可以从C获取_coordinates重塑信息。我没有看到任何用于检索这些属性的公共API方法,但这并不能阻止“严肃”的Python程序员。在此测试用例中,它从coordinates的形状生成D

Quadmesh创建于:

    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)

get_array github存储库中搜索matplotlib并没有获得多次点击。

我挖了一下pcolor代码。它返回PolyCollections img而不是Quadmesh。它包含绘制四边形集合的信息。

例如,在我输入10x20的测试用例中,img._paths是200 Path个对象的列表

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))

它有五个坐标对,绘制四边形边界所需的xy点,其颜色值对应C[0](以平面形式)。

因此,所有X Y网格信息现在都在这些Path个对象中编码。它不是绘制网格,而是绘制200个彩色方块(四边形)。 PolyCollections代码并不假设方块处于任何顺序或甚至相互接触。大局已被一堆独立的小图片所取代。

您可以将这些四边形重新组合成网格,寻找匹配的顶点等等。但这将是很多工作。