【问题标题】:matplotlib table: individual colormap for each column's rangematplotlib 表:每列范围的单独颜色图
【发布时间】:2020-03-17 19:10:52
【问题描述】:

我正在使用 matplotlib 创建一个 5 行 4 列的表。我想使用颜色显示每个单独列中所有条目的值差异。理想情况下,我想使用针对每列个性化的颜色图比例,这意味着该列的颜色图的比例将具有该列值的范围。

澄清一下 - 在第二列中,值介于 800-1200 之间,但第一列值介于 120-230 之间。当在整个表的范围内应用相同的颜色图时,与颜色图范围为 120-230 而不是 120-1200 时相比,第一列中值之间的差异定义得更少。

这似乎不适用于 matplotlib,因为颜色图适用于整个表格。我想要的也可能只是一个糟糕且令人困惑的演示文稿,所以如果有更好的方式来展示我想要的东西,请告诉我!

这就是我现在拥有的:

fig, ax = plt.subplots()

rows = ['%d nodes' % x for x in (10, 30, 50, 75, 100)]
columns=['TP', 'TN', 'FP', 'FN']

conf_data = np.array(
[[ 230,  847,  784,  208],
 [ 156, 1240,  391,  282],
 [ 146, 1212,  419,  292],
 [ 130, 1148,  483,  308],
 [ 122, 1173,  458,  316]]
)  

normal = plt.Normalize(np.min(conf_data), np.max(conf_data))
fig.patch.set_visible(False)
ax.axis('off')
ax.axis('tight')
ax.table(cellText=conf_data,
         rowLabels=rows,
         colLabels=columns,
         cellColours=cm.GnBu(normal(conf_data)),
         loc='center',
         colWidths=[0.1 for x in columns])
fig.tight_layout()
plt.show()

【问题讨论】:

    标签: python matplotlib datatable


    【解决方案1】:

    您可以计算每列的范数:

    import matplotlib.cm as cm
    fig, ax = plt.subplots()
    
    rows = ['%d nodes' % x for x in (10, 30, 50, 75, 100)]
    columns=['TP', 'TN', 'FP', 'FN']
    
    conf_data = np.array(
    [[ 230,  847,  784,  208],
     [ 156, 1240,  391,  282],
     [ 146, 1212,  419,  292],
     [ 130, 1148,  483,  308],
     [ 122, 1173,  458,  316]]
    )  
    
    colores = np.zeros((conf_data.shape[0], conf_data.shape[1], 4))
    for i in range(conf_data.shape[1]):
        col_data = conf_data[:, i]
        normal = plt.Normalize(np.min(col_data), np.max(col_data))
        colores[:, i] = cm.Reds(normal(col_data))
    
    #fig.patch.set_visible(False)
    ax.axis('off')
    ax.axis('tight')
    ax.table(cellText=conf_data,
             rowLabels=rows,
             colLabels=columns,
             cellColours=colores,
             loc='center',
             colWidths=[0.1 for x in columns])
    fig.tight_layout()
    plt.show()
    

    【讨论】:

      【解决方案2】:

      您可以减去每列的最小值并除以它们的ptpnp.ptp 或峰到峰距离是最大值和最小值之间的差异。将其保存到一个新数组中以用于颜色值。

      为避免最高值出现过深的蓝色,您可以将结果乘以 0.8 之类的值。 (或者,您可以更改文本颜色,这需要一些 additional code。)

      import numpy as np
      from matplotlib import pyplot as plt
      
      fig, ax = plt.subplots()
      
      rows = ['%d nodes' % x for x in (10, 30, 50, 75, 100)]
      columns = ['TP', 'TN', 'FP', 'FN']
      conf_data = np.array([[230, 847, 784, 208],
                            [156, 1240, 391, 282],
                            [146, 1212, 419, 292],
                            [130, 1148, 483, 308],
                            [122, 1173, 458, 316]])
      normed_data = (conf_data - conf_data.min(axis=0, keepdims=True)) / conf_data.ptp(axis=0, keepdims=True)
      
      fig.patch.set_visible(False)
      ax.axis('off')
      ax.axis('tight')
      table = ax.table(cellText=conf_data,
                       rowLabels=rows,
                       colLabels=columns,
                       cellColours=plt.cm.GnBu(normed_data*0.8),
                       loc='center',
                       colWidths=[0.1 for x in columns])
      table.scale(2, 2) # make table a little bit larger
      fig.tight_layout()
      plt.show()
      

      在两个不同颜色贴图的结果下方:左侧的“GnBu”,标准值介于 0 和 0.8 之间,右侧的“coolwarm”,标准值介于 0.1 和 0.9 之间

      PS:另一种提高单元格文本和背景颜色对比度的方法是设置每个单元格的alpha:

      for cell in table._cells:
          table._cells[cell].set_alpha(.6)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多