【问题标题】:matplotlib - Large Heatmapmatplotlib - 大型热图
【发布时间】:2016-01-21 02:03:57
【问题描述】:

我尝试在网站上搜索解决方案,但没有找到适合我的解决方案。 我正在尝试绘制一个非常大的热图 - x 轴有 21 个容器,y 轴有 18 个。我正在从 CSV 读取数据,并且在大多数情况下,单元格是空的 - 除了少数.我也在尝试标记轴。

当我绘制热图时,它并没有显示整个事情。我不确定是图形格式还是热图有问题。如果我遗漏任何格式,则该图可以工作 - 但它不会显示所有行/列。当我尝试更改轴限制或设置图形的大小时,它基本上会破坏绘图并且值不会准确显示。

如何让它显示所有列和行,即使值单元格是空的?

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

x_labels = ['A','B','C','D','E','F'
     'G','H','I','J','K','L',
     'M','N','O','P','Q','R',
     'S','T','U']
y_labels =['A','B','C','D','E','F','G','H','I','J',
     'K','L','M','N','O','P','Q','R']

#reading in a CSV, data in the file is mostly empty - only 3 of the cells have values in them.  I included a link to what the .csv looks like
metrics = pd.read_csv("filename.csv", index_col=0)

fig, ir = plt.subplots()
heatmap = ir.pcolor(metrics, cmap=plt.cm.Spectral)

#trying to set the axis labels.  Should this reference the column and row labels in the csv instead of the variable I created?
ir.set_xticklabels(x_labels, minor=False)
ir.set_yticklabels(y_labels, minor=False)

ir.invert_yaxis()

plt.show()

下面是csv 文件的截图:

这是我得到的情节

这是打印数据框的屏幕截图

【问题讨论】:

  • 您是否检查过所有数据是否正确传输到变量metrics?也许您可以通过删除 .csv 导入来减少示例并生成虚拟数据以在 python 中进行测试。
  • Here 是一个可能有用的示例。首先检查数据是否正确加载,然后确保其绘制正确。
  • 我做了一个简单的 print(metrics) 并且输出显示整个 csv 被正确读取。
  • 我认为问题实际上可能出在轴标签的格式上。我要么必须缩小字体,要么旋转单词以垂直显示。关于如何做到这一点的任何提示?
  • 您能否上传您当前情节的图片,以便我们查看问题所在?

标签: python matplotlib


【解决方案1】:

发生的情况是您正在为刻度设置标签,但没有更改它们的位置。

如果您想在每个单元格中添加刻度标签,则需要指定您也希望在其中添加刻度。

例如,您可以执行以下操作:

ax.set(xticks=np.arange(len(xlabels)), xticklabels=xlabels,
       yticks=np.arange(len(ylabels)), yticklabels=ylabels)

您可能还希望将 x/y 范围限制在数据的范围内。

此外,您可以使用imshow(data, interpolation='nearest')matshow(data) 代替pcolor。首先,它们要快得多。其次,默认范围会将每个像元居中放在整数值上,而不是将像元的放在整数值上。此外,matshow/imshow 会将轴的范围限制为数据的范围。

例如,使用pcolor 我们会得到:

import numpy as np
import matplotlib.pyplot as plt

labels = 'ABCDEFGHIKJLMNOPQRSTUV'
data = np.random.random((len(labels), len(labels)))

fig, ax = plt.subplots()
ax.pcolor(data)
ax.axis('tight')
ax.set(xticks=np.arange(len(labels)), xticklabels=labels,
       yticks=np.arange(len(labels)), yticklabels=labels)
plt.show()

使用matshow,我们可以这样做:

import numpy as np
import matplotlib.pyplot as plt

labels = 'ABCDEFGHIKJLMNOPQRSTUV'
data = np.random.random((len(labels), len(labels)))

fig, ax = plt.subplots()
ax.matshow(data)
ax.set(xticks=np.arange(len(labels)), xticklabels=labels,
       yticks=np.arange(len(labels)), yticklabels=labels)
plt.show()

【讨论】:

    【解决方案2】:

    我认为 matshow 比 pcolor 更受欢迎。但是您的问题是刻度位置,因此您也需要更改它们,而不仅仅是标签:

    ir.matshow(metrics, cmap=plt.cm.Spectral)
    
    ir.set_xticks(range(len(x_labels)))
    ir.set_xticklabels(x_labels)
    ir.set_yticks(range(len(y_labels)))
    ir.set_yticklabels(y_labels)
    

    在您的情况下,自动生成的 x/yticks 位置是:

    array([  0.,   5.,  10.,  15.,  20.,  25.])
    

    并且您传递的标签将转到前 6 个标签的这些位置,因为您只有 6 个已定义的刻度位置。这就是您在 x 轴上看到的 A、B、C、D、E 和 F。因此,您可以通过以下方式快速解决此问题:

    ir.set_xticklabels(x_labels[::5])
    

    而不是

    ir.set_xticklabels(x_labels)
    

    您会在正确的位置获得AFJPU 作为标签。但是如果你想要所有标签,你需要创建刻度的位置

    仍然是x/ylim的问题,使用matshow时会自动设置。 matshow 的另一个优点是将标签集中在列或行中(如 Joe Kington 的回答所示)。但是在这种情况下,你也需要定义你的刻度位置,因为使用matshowxticks 甚至更奇怪(不知道他们为什么像他那样做,也许它属于正确设置纵横比),反正你有这样的东西:

    xticks: [-5.0, 0.0, 5.0, 10.0, 15.0, 20.0, 25.0]
    labels: [u'', u'0', u'5', u'10', u'15', u'20', u'']
    

    因此,如果您不重新定义 xticks,您的第一个标签将位于绘图之外(位置 -5)。

    HTH

    【讨论】:

      【解决方案3】:

      @JoeKington 的回答是正确的 - 您需要在设置刻度标签之前设置刻度位置。

      另一种方法是使用matplotlib.ticker 模块,并使用MultipleLocator,设置为1 的倍数 - 即每个单元格打勾。

      对于您的示例,它看起来像:

      import matplotlib.pyplot as plt
      import pandas as pd
      import numpy as np
      import matplotlib.ticker as ticker
      
      x_labels = ['A','B','C','D','E','F'
           'G','H','I','J','K','L',
           'M','N','O','P','Q','R',
           'S','T','U']
      y_labels =['A','B','C','D','E','F','G','H','I','J',
           'K','L','M','N','O','P','Q','R']
      
      #reading in a CSV, data in the file is mostly empty - only 3 of the cells have values in them.  I included a link to what the .csv looks like
      metrics = pd.read_csv("filename.csv", index_col=0)
      
      fig, ir = plt.subplots()
      heatmap = ir.pcolor(metrics, cmap=plt.cm.Spectral)
      
      ir.xaxis.set_major_locator(ticker.MultipleLocator(1))
      ir.yaxis.set_major_locator(ticker.MultipleLocator(1))
      
      ir.set_xticklabels(x_labels, minor=False)
      ir.set_yticklabels(y_labels, minor=False)
      
      ir.invert_yaxis()
      
      plt.show()
      

      【讨论】:

      • 谢谢 - 设置刻度位置让它工作!谢谢大家。
      猜你喜欢
      • 1970-01-01
      • 2021-01-14
      • 2021-01-14
      • 2020-09-22
      • 2014-05-07
      • 2015-04-15
      • 1970-01-01
      相关资源
      最近更新 更多