代码之家  ›  专栏  ›  技术社区  ›  ClimateUnboxed

如何使用patches.PathPatch为矩形指定颜色列表?

  •  1
  • ClimateUnboxed  · 技术社区  · 7 年前

    我想画一个由彩色矩形组成的图,我一直在用这个例子 https://matplotlib.org/gallery/misc/histogram_path.html#sphx-glr-gallery-misc-histogram-path-py 作为指导:

    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.patches as patches
    import matplotlib.path as path
    
    fig, ax = plt.subplots()
    
    # Fixing random state for reproducibility
    np.random.seed(19680801)
    
    data = np.random.randn(1000)
    n, bins = np.histogram(data, 50)
    
    # get the corners of the rectangles for the histogram
    left = np.array(bins[:-1])
    right = np.array(bins[1:])
    bottom = np.zeros(len(left))
    top = bottom + n
    
    XY = np.array([[left, left, right, right], [bottom, top, top, bottom]]).T
    
    # get the Path object
    barpath = path.Path.make_compound_path_from_polys(XY)
    
    # make a patch out of it
    patch = patches.PathPatch(barpath)
    ax.add_patch(patch)
    
    # update the view limits
    ax.set_xlim(left[0], right[-1])
    ax.set_ylim(bottom.min(), top.max())
    
    plt.show()
    

    我想为每个矩形不同的颜色,并认为我可以做到这一点,使用在cols和设置浮动列表

    patch=patches.PathPatch(barpath,fill=True,color=cols
    ,cmap='CMRmap')
    

    但是我得到“无效的rgba arg”,这个例程是否只识别RGB列表?

    2 回复  |  直到 7 年前
        1
  •  2
  •   ClimateUnboxed    5 年前

    A matplotlib.patches.PathPatch 有一个单一的脸颜色。它不能用来给它的部分着色。这是在 the example

    可以使用 均质特性 使用PathCollection更有效。

    and colorize its bars bars 就是使用 PolyCollection .

    import numpy as np; np.random.seed(19680801)
    import matplotlib.pyplot as plt
    import matplotlib.patches as patches
    import matplotlib.path as path
    import matplotlib.collections
    import matplotlib.cm
    
    data = np.random.randn(1000)
    
    
    def compoundpathhist(data, nbins=50):
        n, bins = np.histogram(data, nbins)
        # get the corners of the rectangles for the histogram
        left = np.array(bins[:-1])
        right = np.array(bins[1:])
        bottom = np.zeros(len(left))
        top = bottom + n
        
        
        # we need a (numrects x numsides x 2) numpy array for the path helper
        # function to build a compound path
        XY = np.array([[left, left, right, right], [bottom, top, top, bottom]]).T
        
        # get the Path object
        barpath = path.Path.make_compound_path_from_polys(XY)
        
        # make a patch out of it
        patch = patches.PathPatch(barpath)
        fig, ax = plt.subplots()
        ax.add_patch(patch)
        # update the view limits
        ax.set_xlim(left[0], right[-1])
        ax.set_ylim(bottom.min(), top.max())
    
        fig.savefig("bartest.png")
            
    
    def polyhist(data, nbins=50, colors=True):
        n, bins = np.histogram(data, nbins)
        # get the corners of the rectangles for the histogram
        left = np.array(bins[:-1])
        right = np.array(bins[1:])
        bottom = np.zeros(len(left))
        top = bottom + n
        # we need a (numrects x numsides x 2) numpy array to be used as 
        # vertices for the PolyCollection
        XY = np.array([[left, left, right, right], [bottom, top, top, bottom]]).T
        
        c=None
        if colors:
            c = matplotlib.cm.RdYlBu(n/n.max())
        pc = matplotlib.collections.PolyCollection(XY, facecolors=c)
        
        fig, ax = plt.subplots()
        ax.add_collection(pc)
        # update the view limits
        ax.set_xlim(left[0], right[-1])
        ax.set_ylim(bottom.min(), top.max())
        
        fig.savefig("bartest.png")
            
    
    
    def hist_c(data, nbins=50, colors=True):
    
        fig, ax = plt.subplots()
        n, bins, patches = ax.hist(data, nbins)
    
        if colors:
            cols = matplotlib.cm.RdYlBu(n/n.max())
            for p,c in zip(patches, cols):
                p.set_facecolor(c)
    
        # update the view limits
        ax.set_xlim(bins.min(), bins.max())
        ax.set_ylim(n.min(), n.max())
    
        fig.savefig("bartest.png")
    
            
    compoundpathhist(data, nbins=50)
    polyhist(data, nbins=50)
    hist_c(data, nbins=50, colors=True)
    
    plt.show()
    

    enter image description here

    • 第一个( compoundpathhist
    • 第二个( polyhist )不使用单个补丁,而是使用 多集 . 这个 多集 的FaceColor可以通过colormap设置。
    • 第三个( hist_c )是一种适用于单根棒材着色的常用解决方案。

    现在我们可以计时这三个函数。我使用了90000个数据点和50500和5000个垃圾箱。

    enter image description here

    我们观察到,对于通常数量的~50箱,这些方法基本上没有区别。但是,对于数量较多的垃圾箱 hist 方法花费的时间明显更长。即使是5000个垃圾箱,两者之间也几乎没有区别 复合病学家 方法(不能使用颜色)和 多面手 ,可以使用颜色。因此,在不牺牲效率的情况下,这是一个有用的替代方案。 顺便说一下,在各自的功能中使用颜色和不使用颜色几乎没有区别。

        2
  •  3
  •   Sheldore    7 年前

    PathPatch Path 完全不需要。您可以删除 edgecolor='black' 如果你不想要黑边的话。

    解释 patches plt.hist CMRmap . 最后,在 设置每个补丁的颜色。

    import numpy as np
    import matplotlib.pyplot as plt
    
    fig, ax = plt.subplots()
    
    # Fixing random state for reproducibility
    np.random.seed(19680801)
    
    data = np.random.randn(1000)
    N, bins, patches = plt.hist(data, bins=50, edgecolor='black')
    
    cm = plt.get_cmap('CMRmap')
    for i in range(len(patches)):
        color = cm(1.*i/len(patches))  
        patches[i].set_facecolor(color)
    

    enter image description here