为了账号安全,请及时绑定邮箱和手机立即绑定

使用 patch.Rectangle 绘制不规则光栅图时避免缓慢循环

使用 patch.Rectangle 绘制不规则光栅图时避免缓慢循环

凤凰求蛊 2021-10-26 10:33:23
我写了一个代码来制作一个不规则的光栅图(即光栅矩形的大小是可变的)。下面是一个最小的可重现示例。问题是在我的示例中循环块非常慢(每个图都有很多矩形,并且有很多图要制作)。我试图将坐标转换为元组列表,但这引发了错误。是否有可能让 patch.Rectangle 返回一个补丁列表,而不是一个,这样我就可以摆脱补丁上的循环并加速代码?import matplotlib.pyplot as pltimport matplotlib.patches as patchesimport numpy as npimport matplotlib.colorbar as cbarfig,ax=plt.subplots(1)rng=6plt.ylim(0,rng)plt.xlim(0,rng)N = 30x = np.random.rand(N)*rngy = np.random.rand(N)*rngs = np.random.rand(N)colors=np.random.rand(N)normal = plt.Normalize(0,1) # my numbers from 0-1cmap=plt.cm.RdYlBu_rc=cmap(colors)for i in range(N):    val=0.5    rect=patches.Rectangle((x[i],y[i]),s[i],s[i],                            edgecolor='black',                            linewidth = 1,                            facecolor = c[i],                            )     ax.add_patch(rect)cax, _ = cbar.make_axes(ax) cb2 = cbar.ColorbarBase(cax, cmap=cmap,norm=normal) plt.savefig("test.png")
查看完整描述

2 回答

?
慕桂英3389331

TA贡献2036条经验 获得超8个赞

一句话总结:用一个PolyCollection。


使用集合绘制多个形状肯定比绘制单个矩形更有效。在其他答案建议使用PatchCollection。更有效的是使用PolyCollection.


原因有两个:


在 PolyCollection 中,您不需要单独创建每个补丁

只定义一个形状就足够了,并且只指定大小、颜色和偏移量。

我对有关颜色定义(最好让集合为您完成)和颜色条(使用集合,而不是独立的颜色条)的代码进行了一些修改


import matplotlib.pyplot as plt

import matplotlib.patches as patches

import numpy as np

from matplotlib.collections import PatchCollection, PolyCollection

import matplotlib.transforms as mtrans

补丁集:


def patchcoll(N, show=False):

    fig,ax=plt.subplots()


    rng=6

    plt.ylim(0,rng+1)

    plt.xlim(0,rng+1)


    x = np.random.rand(N)*rng

    y = np.random.rand(N)*rng

    s = np.random.rand(N)

    c = np.random.rand(N)

    norm = plt.Normalize(0,1) # my numbers from 0-1

    cmap=plt.cm.RdYlBu_r


    pat = []


    for i in range(N):

        rect=patches.Rectangle((x[i],y[i]),s[i],s[i])

        pat.append(rect)


    col = PatchCollection(pat, cmap=cmap, norm=norm)

    col.set_array(c)

    col.set_edgecolor('k')

    col.set_linewidth(1.)

    ax.add_collection(col)



    fig.colorbar(col)

    if show:

        plt.show()

    else:

        fig.canvas.draw() 


    plt.close()

多集合:


def polycoll(N, show=False):

    fig,ax=plt.subplots()


    rng=6

    plt.ylim(0,rng)

    plt.xlim(0,rng)


    x = np.random.rand(N)*rng

    y = np.random.rand(N)*rng

    s = np.random.rand(N)

    c = np.random.rand(N)

    norm = plt.Normalize(0,1) # my numbers from 0-1

    cmap=plt.cm.RdYlBu_r


    offsets = np.c_[x,y]

    verts = list(zip([0,1,1,0,0], [0,0,1,1,0]))


    col = PolyCollection([verts], sizes=s, offsets=offsets, 

                         transOffset=mtrans.IdentityTransform(),

                         offset_position="data", cmap=cmap, norm=norm)


    col.set_array(c)

    col.set_edgecolor('k')

    col.set_linewidth(1.)

    ax.add_collection(col)


    fig.colorbar(col)


    if show:

        plt.show()

    else:

        fig.canvas.draw() 


    plt.close()

单个矩形:


def rectangles(N, show=False):

    fig,ax=plt.subplots()


    rng=6

    plt.ylim(0,rng)

    plt.xlim(0,rng)


    x = np.random.rand(N)*rng

    y = np.random.rand(N)*rng

    s = np.random.rand(N)

    c = np.random.rand(N)

    norm = plt.Normalize(0,1) # my numbers from 0-1


    cmap=plt.cm.RdYlBu_r


    for i in range(N):

        rect=patches.Rectangle((x[i],y[i]),s[i],s[i], 

                               facecolor=cmap(norm(c[i])), edgecolor="k", linewidth=1)

        ax.add_patch(rect)



    sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm)

    sm.set_array([])

    fig.colorbar(sm)


    if show:

        plt.show()

    else:

        fig.canvas.draw() 


    plt.close()

运行所有:


patchcoll(30, show=True)

polycoll(30,show=True)

rectangles(30,show=True)

定时

因为N=1000我得到


%timeit(rectangles(1000))

757 ms ± 4.26 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)


%timeit(patchcoll(1000))

184 ms ± 462 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)


%timeit(polycoll(1000))

58.3 ms ± 146 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

因此,在这种情况下,使用 a 的PatchCollection效率比单个矩形高 3 倍,使用 a 的PolyCollection效率比 a 高 3 倍PatchCollection。


查看完整回答
反对 回复 2021-10-26
  • 2 回答
  • 0 关注
  • 276 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信