matplotlib - 大热图

时间:2016-01-19 14:30:40

标签: python matplotlib

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

当我绘制热图时,它并不显示整个事物。我不确定这是图形格式或热图的问题。如果我保留任何格式,则绘图有效 - 但它不显示所有行/列。当我尝试更改轴限制或设置图形的大小时,它基本上会打破图,并且值不会准确显示。

如果值单元格为空,如何使其显示所有列和行?

console.log(parseInt(bp_s) + 5);

以下是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 file

这是我得到的情节 current_heatmap

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

3 个答案:

答案 0 :(得分:2)

发生了什么事情是您为蜱设置了标签,但没有改变它们的位置。

如果你想在每个单元格中使用ticklabels,那么他们也需要指明你也喜欢那里的蜱虫。

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

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。首先,他们的速度要快得多。其次,默认范围将居中每个单元格超过整数值,而不是将单元格的 edge 置于整数值。此外,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()

enter image description here

使用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()

enter image description here

答案 1 :(得分:1)

我认为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的回答所示)。但在这种情况下,你也需要定义你的刻度线位置,因为matshow xticks甚至更奇怪(不确定为什么他们这样做,也许它属于设置正确的方面),无论如何你有这样的东西:

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

答案 2 :(得分:0)

@ 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()