代码之家  ›  专栏  ›  技术社区  ›  Trenton McKinney ivirshup

当两个轴都是分类的、y轴是多索引且值是分类的时,如何绘制?

  •  1
  • Trenton McKinney ivirshup  · 技术社区  · 7 年前

    提供以下数据:

    DC,Mode,Mod,Ven,TY1,TY2,TY3,TY4,TY5,TY6,TY7,TY8
    Intra,S,Dir,C1,False,False,False,False,False,True,True,False
    Intra,S,Co,C1,False,False,False,False,False,False,False,False
    Intra,M,Dir,C1,False,False,False,False,False,False,True,False
    Inter,S,Co,C1,False,False,False,False,False,False,False,False
    Intra,S,Dir,C2,False,True,True,True,True,True,True,False
    Intra,S,Co,C2,False,False,False,False,False,False,False,False
    Intra,M,Dir,C2,False,False,False,False,False,False,False,False
    Inter,S,Co,C2,False,False,False,False,False,False,False,False
    Intra,S,Dir,C3,False,False,False,False,True,True,False,False
    Intra,S,Co,C3,False,False,False,False,False,False,False,False
    Intra,M,Dir,C3,False,False,False,False,False,False,False,False
    Inter,S,Co,C3,False,False,False,False,False,False,False,False
    Intra,S,Dir,C4,False,False,False,False,False,True,False,True
    Intra,S,Co,C4,True,True,True,True,False,True,False,True
    Intra,M,Dir,C4,False,False,False,False,False,True,False,True
    Inter,S,Co,C4,True,True,True,False,False,True,False,True
    Intra,S,Dir,C5,True,True,False,False,False,False,False,False
    Intra,S,Co,C5,False,False,False,False,False,False,False,False
    Intra,M,Dir,C5,True,True,False,False,False,False,False,False
    Inter,S,Co,C5,False,False,False,False,False,False,False,False
    

    import pandas as pd
    import matplotlib.pyplot as plt
    import numpy as np
    

    复制我的 DataFrame

    df = pd.read_clipboard(sep=',')
    

    我想创建一个情节,传达与我的例子相同的信息,但不一定具有相同的形状(我愿意接受建议)。我还想把鼠标悬停在这个颜色上,并选择合适的 Ven 显示(例如C1,而不是1):

    到目前为止,提供的两个解决方案都很有帮助,而且每一个都完成了我所要寻找的不同方面。但是,我想解决的关键问题是,在编辑之前没有明确说明:

    我想在不转换的情况下执行绘图 文氏 给一个 int

    enter image description here

    我遇到的问题是数据是分类的,而y轴是多索引的。

    我已经做了以下工作来转换 数据帧 :

    # replace False witn nan
    df = df.replace(False, np.nan)
    
    # replace True with a number representing Ven (e.g. C1 = 1)    
    def rep_ven(row):
        return row.iloc[4:].replace(True, int(row.Ven[1]))
    
    df.iloc[:, 4:] = df.apply(rep_ven, axis=1)
    
    # drop the Ven column
    df = df.drop(columns=['Ven'])
    
    # set multi-index
    df_m = df.set_index(['DC', 'Mode', 'Mod'])
    

    绘制转换的 数据帧 生产:

    plt.figure(figsize=(20,10))
    heatmap = plt.imshow(df_m)
    plt.xticks(range(len(df_m.columns.values)), df_m.columns.values)
    plt.yticks(range(len(df_m.index)), df_m.index)
    plt.show()
    

    enter image description here

    文氏 . 这是数据的一个子集,因此图形将非常长,包含所有数据。

    2 回复  |  直到 7 年前
        1
  •  1
  •   rje    7 年前

    这是我的解决办法。我只是将样式应用于数据帧,而不是打印,请参见 https://pandas.pydata.org/pandas-docs/stable/style.html

    # Transform Ven values from "C1", "C2" to 1, 2, ..
    df['Ven'] = df['Ven'].str[1]
    
    # Given a specific combination of dc, mode, mod, ven, 
    # do we have any True cells?
    g = df.groupby(['DC', 'Mode', 'Mod', 'Ven']).any()
    
    # Let's drop any rows with only False values
    g = g[g.any(axis=1)]
    
    # Convert True, False to 1, 0
    g = g.astype(int)
    
    # Get the values of the ven index as an int array
    # Note: we don't want to drop the ven index!!
    # Otherwise styling won't work
    ven = g.index.get_level_values('Ven').values.astype(int)
    
    # Multiply 1 and 0 with Ven value
    g = g.mul(ven, axis=0)
    
    # Sort the index
    g.sort_index(ascending=False, inplace=True)
    
    # Now display the dataframe with styling
    
    # first we get a color map
    import matplotlib
    cmap = matplotlib.cm.get_cmap('tab10')
    
    def apply_color_map(val):
        # hide the 0 values
        if val == 0:
            return 'color: white; background-color: white' 
        else:
            # for non-zero: get color from cmap, convert to hexcode for css
            s = "color:white; background-color: " + matplotlib.colors.rgb2hex(cmap(val))
            return s
    g
    g.style.applymap(apply_color_map)
    

    可用的matplotlib颜色映射可以在这里看到: Colormap reference Choosing a colormap

    The result

        2
  •  1
  •   Ernest Li    7 年前

    解释 TY1 - TY8 都是 nan this answer 作为创建要显示的交互式注释的起点 Ven .

    import pandas as pd
    import matplotlib.pyplot as plt
    import numpy as np
    
    df = pd.read_clipboard(sep=',')
    
    # replace False witn nan
    df = df.replace(False, np.nan)
    
    # replace True with a number representing Ven (e.g. C1 = 1)    
    def rep_ven(row):
        return row.iloc[4:].replace(True, int(row.Ven[1]))
    
    df.iloc[:, 4:] = df.apply(rep_ven, axis=1)
    
    # drop the Ven column
    df = df.drop(columns=['Ven'])
    
    idx = df[['TY1','TY2', 'TY3', 'TY4','TY5','TY6','TY7','TY8']].dropna(thresh=1).index.values
    df = df.loc[idx,:].sort_values(by=['DC', 'Mode','Mod'], ascending=False)
    
    # set multi-index
    df_m = df.set_index(['DC', 'Mode', 'Mod'])
    
    
    plt.figure(figsize=(20,10))
    heatmap = plt.imshow(df_m)
    plt.xticks(range(len(df_m.columns.values)), df_m.columns.values)
    plt.yticks(range(len(df_m.index)), df_m.index)
    plt.show()
    

    enter image description here