对数刻度Matplotlib PatchCollection颜色 [英] Log Scale Matplotlib PatchCollection Colors
问题描述
我有一个函数,可以生成异构网格,然后绘制补丁.它为每个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屋!