小编典典

使用Matplotlib的单个pcolormesh具有多个颜色图

python

我正在创建一个GUI,其中有多个记录(“事物”)和字段的实时“时间点”数据。记录基于字段是可比较的,但是字段不一定是相关的(至少不是相同比例)。对于我最终的GUI,我希望主页是一个热图(实际上是一堆基于列(字段)的一维热图,然后,如果单击其中一个,它将提供时间序列历史记录和其他一些图表)。

无论如何,我在这里追求的是尝试获取初始热图以显示我想要的方式。到目前为止,我可以通过从Matplotlib中获取pcolormesh来本质上显示基于字段的单个一维热图,方法是对其进行黑客攻击并根据列的百分位数进行热映射,然后在顶部添加实际值的文本。

但是,正如我所说,字段不一定是相关的,我希望能够为每个字段使用单独的颜色图。 例如:说字段3和4在质量上是相互关联的,但与字段0-3没有关系-
因此最好将那些映射为说“绿色”而不是“冷色”。

到目前为止,这是我的代码以及生成的pcolormesh / heatmap:

import pandas as pd
import matplotlib.pyplot as plt

def DFPercentiles(df,bycols=True):
    p=pd.DataFrame(index=df.index,columns=df.columns)
    if bycols!=True:
        for j in df.index:
            for i in df.columns:
                p.loc[j,i]=(df.loc[j,i]-min(df.loc[j,:]))/(max(df.loc[j,:])-min(df.loc[j,:]))
    else:
        for i in df.index:
            for j in df.columns:
                p.loc[i,j]=(df.loc[i,j]-min(df.loc[:,j]))/(max(df.loc[:,j])-min(df.loc[:,j]))
    return p

def Heatmap(df,figsize='auto'):
    if figsize=='auto':
        figsize=[shape(df)[1],shape(df)[0]/2]
    fig=figure(figsize=figsize)
    pdf=array(DFPercentiles(df,bycols=True)).astype(float)[::-1]
    plt.pcolormesh(pdf,cmap=cm.coolwarm,alpha=0.8)
    plt.yticks(arange(0.5,len(df)),df.index[::-1])
    plt.xticks(arange(0.5,len(df.columns)),df.columns)
    for y in range(df.shape[0]):
        for x in range(df.shape[1]):
            plt.text(x + 0.5, y + 0.5, '%.3f' % df[::-1].iloc[y, x],
                     horizontalalignment='center',
                     verticalalignment='center',
                     )
    return plt

hmap=Heatmap(mydf)
hmap.show()

阅读 225

收藏
2020-12-20

共1个答案

小编典典

每个色网格图都有一个关联的色图。为了在一张图中使用多个颜色图,因此我看到以下选项:

  1. 单个矩形 :不要使用pcolormesh,而是按照自己的喜好绘制单个矩形。
  2. 创建您的 自定义颜色图 ,其中合并了不同范围内的不同颜色图。例如,将0到0.4的值映射到一个颜色图的颜色,将0.4到1的值映射到另一颜色图的颜色。然后可能看起来像:

    import matplotlib.pyplot as plt
    

    import matplotlib.colors
    import numpy as np

    x,y = np.meshgrid(range(4), range(4))
    z = np.array([[0.2,.3,.95],[.5,.76,0.4],[.3,.1,.6]]).astype(float)
    mask= np.array([[1,0,0],[1,0,0],[1,1,1]]).astype(float)
    Z = z + mask

    c2 = plt.cm.Greens(np.linspace(0,1,128))
    c1 = plt.cm.coolwarm(np.linspace(0,1,128))
    cols = np.vstack((c1, c2))
    cmap=matplotlib.colors.LinearSegmentedColormap.from_list(“q”, cols)

    fig, ax=plt.subplots()
    ax.pcolormesh(x,y,Z, vmin=0, vmax=2, cmap=cmap)

    plt.show()

  3. 屏蔽 数组并绘制几个pcolormesh图。以下示例显示了这样的样子:

        import matplotlib.pyplot as plt
    import numpy as np
    import numpy.ma as ma
    
    x,y = np.meshgrid(range(4), range(4))
    z = np.array([[1,1.3,3],[2.2,2.8,1.8],[3,1,3]]).astype(float)
    mask= np.array([[1,0,0],[1,0,0],[1,1,1]]).astype(bool)
    z1 = np.copy(z)
    z1[mask] = np.nan
    
    z2 = np.copy(z)
    z2[~mask] = np.nan
    
    fig, ax=plt.subplots()
    ax.pcolormesh(x,y,ma.masked_invalid(z1), vmin=1, vmax=3, cmap="coolwarm")
    ax.pcolormesh(x,y,ma.masked_invalid(z2), vmin=1, vmax=3, cmap="Greens")
    
    plt.show()
    
2020-12-20