对数刻度Matplotlib PatchCollection颜色 [英] Log Scale Matplotlib PatchCollection Colors

查看:60
本文介绍了对数刻度Matplotlib PatchCollection颜色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个函数,可以生成异构网格,然后绘制补丁.它为每个bin指定上下 x y 边缘.例如,单个容器由向量 [x0,x1,y0,y1] 定义.这些坐标转换为bin:

  y1 | --------- ||||斌|||y0 | ----------- |x0 x1 

我有一个(Nx4)个网格,其中包含带有 [x0,x1,y0,y1] 列的 N 个垃圾箱.要绘制数据,请执行以下操作:

  z_plot = z_stat/(dx * dy)#``z_stat``是计算出的z值z_plot = z_plot/z_plot.max()#对于任何给定的bin.colors = mpl.cm.jet(z_plot)#让填充数据为白色.colors [z_stat ==填充] =(1.0,1.0,1.0,1.0)#fill = -9999.0(通常).dx = mesh [:, 1]-mesh [:, 0]#x1-x0dy = mesh [:, 3]-mesh [:, 2]#y1-y0.xy = zip(mesh [:, 0],mesh [:, 2])每个的#(x,y)坐标#bin的左下角.补丁= [mpl.patches.Rectangle(xy [i],dx [i],dy [i],#我不想ec = None,lw = 0,fc = colors [i])#可见边缘.对于我在范围内(mesh.shape [0])]补丁= mpl.collections.PatchCollection(补丁,match_original = True)ax.add_collection(补丁)如果z_stat不为None:kwargs = {'orientation':'vertical'}cax,kw = _mpl.colorbar.make_axes_gridspec(plot_ax,** kwargs)cbar = mpl.colorbar.ColorbarBase(cax,cmap = _mpl.cm.jet) 

这是结果:

此问题做了类似的操作,但没有对数刻度颜色.我不知道如何使颜色达到对数刻度.仅仅将 mpl.colors.LogNorm()之类的内容传递给 mpl.colorbar.ColorbarBase()并不适合我.

编辑1 :生成网格.

我有一个函数,可以生成异构网格,然后绘制补丁.它以2D数组开头:

  mesh = [[x00,x10,y00,y01],[x10,x11,y10,y11],...,[xN0,xN1,yN0,yN1] 

我仔细阅读了网格,并将每个容器分成四个部分:

 #y1 | ------ | ---- |x0,x1,y0,y1 =网格[i,:]#|p4 |p3 |xh = [x0 + .5 *(x1-x0)]#| ---- | ---- |<-yh yh = [y0 + .5 *(y1-y0)]#|p1 |p2 |#y0 | -------- | ---- |#x0 ^ -xh x1 

如果每个 [p1,p2,p3,p4] 的数据点数均超过最小数量(例如50个),则替换行 [x0,x1,y0,y1] 与该数组:

  new_mesh = _np.array([[xx,xh,xh,x0],#定义[xh,x1,x1,xh],#4个新箱[y0,y0,yh,yh],#将要替换垃圾箱[yh,yh,y1,y1]]最初由).T#[x0,x1,y0,y1].如果i == 0:#0的边缘是索引的一种特殊情况.mesh_h = _np.concatenate([new_mesh,mesh [1:]])别的:mesh_h = _np.concatenate([mesh [:i],new_mesh,mesh [i + 1:]])mesh = mesh_h#设置新的边. 

解决方案

尽管我无法测试您的确切情况,因为您没有提供一个可独立运行的示例,所以您应该这样做(如果我对所需行为的理解是正确的)能够完成您想要的操作,如下所述.

首先编辑此行以删除颜色和边缘信息的手动设置:

  patches = [mpl.patches.Rectangle(xy [i],dx [i],dy [i],#我不想ec = None,lw = 0,fc = colors [i])#可见边缘.对于我在范围内(mesh.shape [0])] 

它应该看起来像这样:

  patches = [mpl.patches.Rectangle(xy [i],dx [i],dy [i])对于范围(mesh.shape [0])中的i] 

然后将 LogNorm jet 和您的edge参数传递给 PatchCollection .这是因为我们希望matplotlib自身尽可能多地处理,以便它可以为您整理颜色.

  patch_collection = mpl.collections.PatchCollection(patches,cmap = matplotlib.cm.jet,norm = matplotlib.colors.LogNorm(),lw = 0) 

然后使用 set_array 为PatchCollection提供z信息:

  patch_collection.set_array(z_plot) 

最后将集合添加到绘图中,创建颜色栏并显示该图:

  ax.add_collection(patch_collection)plt.colorbar(patch_collection)plt.show() 

此答案很大程度上基于此处给出的示例,可能是有用的./p>

I have a function that generates a heterogeneous mesh and then plots the patches. It specifies the lower and upper x and y edge for every bin. For example, a single bin is defined by the vector [x0, x1, y0, y1]. These coordinates translate to a bin:

    y1|---------|   
      |         |  
      |   bin   | 
      |         |
    y0|---------|
     x0         x1   

I have an (Nx4) mesh that contains N bins with [x0, x1, y0, y1] columns. To plot the data, I do the following:

z_plot  = z_stat / (dx * dy)     # ``z_stat`` is a calculated z-value 
z_plot  = z_plot / z_plot.max()  # for any given bin.

colors = mpl.cm.jet(z_plot)                   # Let fill data be white.
colors[z_stat == fill] = (1.0, 1.0, 1.0, 1.0) # fill=-9999.0, typically.

dx = mesh[:, 1] - mesh[:, 0]  # x1-x0
dy = mesh[:, 3] - mesh[:, 2]  # y1-y0.

xy = zip(mesh[:, 0], mesh[:, 2])  # (x,y) coordinates of each
                                  # bin's lower left corner.

patches = [mpl.patches.Rectangle(xy[i], dx[i], dy[i],         # I dont want
                                 ec=None, lw=0, fc=colors[i]) # visible edges.
            for i in range(mesh.shape[0])
          ]

patches = mpl.collections.PatchCollection(patches, match_original=True)
ax.add_collection(patches)

if z_stat is not None:

    kwargs = {'orientation': 'vertical'}
    cax, kw = _mpl.colorbar.make_axes_gridspec(plot_ax, **kwargs)

    cbar = mpl.colorbar.ColorbarBase(cax, cmap=_mpl.cm.jet)

This is the result:

This question does something similar, but without the logscale colors. I don't know how to get the colors to log scale. Simply passing something like mpl.colors.LogNorm() to mpl.colorbar.ColorbarBase() did not work for me.

EDIT 1: Generating the mesh.

I have a function that generates a heterogeneous mesh and then plots the patches. It starts with a 2D array:

mesh = [[x00, x10, y00, y01], 
        [x10, x11, y10, y11], 
        ..., 
        [xN0, xN1, yN0, yN1]] 

I read through the mesh and divide each bin in four:

#    y1|----|----|          x0, x1, y0, y1 = mesh[i, :]
#      | p4 | p3 |          xh = [x0 + .5*(x1-x0)]
#      |----|----| <- yh    yh = [y0 + .5 *(y1-y0)]
#      | p1 | p2 |
#    y0|----|----|
#     x0    ^-xh x1       

If each of [p1, p2, p3, p4] have more than the minimum number of data points (e.g. 50), I replace row [x0, x1, y0, y1] with this array:

        new_mesh = _np.array([[x0, xh, xh, x0],  # Define the 16 edges of  
                              [xh, x1, x1, xh],  # the 4 new bins that are  
                              [y0, y0, yh, yh],  # going to replace the bin 
                              [yh, yh, y1, y1]]  # originally defined by 
                            ).T                  # [x0, x1, y0, y1].

        if i == 0:  # 0th edge is a special case for indexing.

            mesh_h = _np.concatenate([new_mesh, mesh[1:]])

        else:

            mesh_h = _np.concatenate([mesh[:i], new_mesh, mesh[i+1:]])         


        mesh = mesh_h  # Set the new edges.

解决方案

Although I can't test your exact case as you've not provided an independently runnable example you should (if my understanding of your desired behaviour is correct) be able to accomplish what you want as follows.

Firstly edit this line to remove the manual setting of the colour and edge information:

patches = [mpl.patches.Rectangle(xy[i], dx[i], dy[i],         # I dont want
                                 ec=None, lw=0, fc=colors[i]) # visible edges.
            for i in range(mesh.shape[0])
          ]

It should look something like this:

patches = [mpl.patches.Rectangle(xy[i], dx[i], dy[i]) for i in range(mesh.shape[0])]

Then pass LogNorm, jet and your edge parameter to PatchCollection. This is because we want matplotlib to handle as much as possible by itself so it can sort out the colours for you.

patch_collection = mpl.collections.PatchCollection(patches,cmap=matplotlib.cm.jet, norm=matplotlib.colors.LogNorm(), lw=0)

Then use set_array to give the PatchCollection the z information:

patch_collection.set_array(z_plot)

Finally add the collection to the plot, create the colorbar and show the figure:

ax.add_collection(patch_collection)
plt.colorbar(patch_collection)

plt.show()

This answer is heavily based on the example given here which may be useful.

这篇关于对数刻度Matplotlib PatchCollection颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆