Python热图:更改颜色贴图并使其不对称

时间:2018-03-28 09:24:42

标签: python pandas matplotlib heatmap

我想建立一个这个数据的热图:

import sys
import pandas as pd
import matplotlib
matplotlib.use('Agg')
import matplotlib.ticker as ticker
import matplotlib.cm as cm
import matplotlib as mpl
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
from matplotlib import colors

data_raw = pd.read_csv(sys.argv[1],sep = '\t')
data_raw["curation1"] = pd.Categorical(data_raw["curation1"], data_raw.curation1.unique())
data_raw["curation2"] = pd.Categorical(data_raw["curation2"], data_raw.curation2.unique())
data_matrix = data_raw.pivot("curation1", "curation2", "overlap")

fig = plt.figure()
fig, ax = plt.subplots(1,1, figsize=(12,12))
heatplot = ax.imshow(data_matrix,cmap = 'BuPu')
#ax.set_xticklabels(data_matrix.columns)
#ax.set_yticklabels(data_matrix.index)
tick_spacing = 1
#ax.xaxis.set_major_locator(ticker.MultipleLocator(tick_spacing))
#ax.yaxis.set_major_locator(ticker.MultipleLocator(tick_spacing))
ax.set_title("Overlap")
fig.savefig('output.pdf')

我用这段代码制作了热图:

http://localhost/~user/index.html

输出如下所示:this

我有三个问题:

  1. 在大多数数据颜色非常浅的意义上,您可以看到颜色方案有点“关闭”,并且有一个随机的紫色框表示“0”。理想情况下,我希望这个热图是不同的绿色阴影,最暗的绿色是最高的数字,最轻的(但仍然清晰可见)绿色是最低的数字。我尝试使用'cmap'参数,例如如python教程here中所述,将其更改为“winter”;但我做错了什么。有人可以告诉我具体可以改变这个吗?

  2. 颜色条:我想添加一个颜色条,但我想我需要先解决问题1.

  3. 不对称:如您所见,此图不对称。是否有可能绘制一半的热图(例如,摆脱不必要的线条,并可能将轴标签移动到图的右侧?)如果不是这不是一个大问题因为我可以重新夹具它在powerpoint中。

3 个答案:

答案 0 :(得分:1)

这将解决您的前两个问题 -

fig = plt.figure()
fig, ax = plt.subplots(1,1, figsize=(12,12))
heatplot = ax.imshow(data_matrix,cmap = 'Greens')

cbar = fig.colorbar(heatplot, ticks=[data_raw.overlap.min(), data_raw.overlap.max()])
tick_spacing = 1
ax.set_title("Overlap")

答案 1 :(得分:0)

首先选择适合的色彩图(看看here),为您的目的 Greens 可能会很好。请注意,可以通过将'_ r'添加到名称来反转色彩映射。

由于您的值差异很大,我会使用对数色标。 您可以通过添加idx = pd.MultiIndex.from_tuples([(1, u'one'), (1, u'two'), (2, u'one'), (2, u'two')], names=['foo', 'bar']) idx.set_levels([3, 5], level=0) # works fine idx.set_levels([(1,2),(3,4)], level=0) #TypeError: Levels must be list-like (来自color.LogNorm

来实现此目的

要解决第三个问题,我会将轴移到右上方并删除左下角。

import matplotlib.colors as colors

enter image description here

答案 2 :(得分:0)

我会改用seaborn heatmap函数。色彩映射Greens应该可以解决您想要的配色方案。如果您愿意,可以查看matplotlib docs中的其他选项。

只是hihglight和 ctrl + c 你问的数据集并运行下面的代码段:

# Imports
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np

data_raw = pd.read_clipboard(sep='\\s+')
data_matrix = data_raw.pivot("curation1", "curation2", "overlap")
data_matrix = data_matrix.fillna(0)

# A heatmap function that builds on the seaborn heatmap function
def HeatMap_function(df, title, transpose = True, colors = 'Greens', dropDuplicates = True):

    if transpose:
        df = df.T

    if dropDuplicates:    
        mask = np.zeros_like(df, dtype=np.bool)
        mask = np.invert(mask)
        mask[np.triu_indices_from(mask)] = False

    # Set background color / chart style
    sns.set_style(style = 'white')

    # Set up  matplotlib figure
    f, ax = plt.subplots(figsize=(11, 9))
    ax.set_title(title)

    # Add diverging colormap from red to blue
    # cmap = sns.diverging_palette(250, 10, as_cmap=True)
    cmap=plt.get_cmap(colors)

    # Draw correlation plot with or without duplicates
    if dropDuplicates:
        sns.heatmap(df, mask=mask, cmap=cmap, 
                square=True,
                linewidth=.5, cbar_kws={"shrink": .5}, ax=ax)
    else:
        sns.heatmap(df, cmap=cmap, 
                square=True,
                linewidth=.5, cbar_kws={"shrink": .5}, ax=ax)

    ax.xaxis.set_ticks_position('top')
    ax.yaxis.set_ticks_position('right')

# A testrun
HeatMap_function(df = data_matrix, title = 'Overlap', transpose = False,
                 colors = 'Greens', dropDuplicates = True)

你会得到这个:

enter image description here

现在,您还可以使用transposecolorsdropDuplicates的不同组合来更改地块的布局。