seaborn热图情节

时间:2016-08-08 18:31:41

标签: python pandas matplotlib seaborn

我正在使用此处的数据来构建使用seaborn和pandas的热图。

输入csv文件位于:https://www.dropbox.com/s/5jc1vr6u8j7058v/LUH2_trans_matrix.csv?dl=0

代码:

    import pandas
    import seaborn.apionly as sns

    # Read in csv file
    df_trans = pandas.read_csv('LUH2_trans_matrix.csv')

    sns.set(font_scale=0.8)
    cmap = sns.cubehelix_palette(start=2.8, rot=.1, light=0.9, as_cmap=True)
    cmap.set_under('gray')  # 0 values in activity matrix are shown in gray (inactive transitions)
    df_trans = df_trans.set_index(['Unnamed: 0'])
    ax = sns.heatmap(df_trans, cmap=cmap, linewidths=.5, linecolor='lightgray')

    # X - Y axis labels
    ax.set_ylabel('FROM')
    ax.set_xlabel('TO')

    # Rotate tick labels
    locs, labels = plt.xticks()
    plt.setp(labels, rotation=0)
    locs, labels = plt.yticks()
    plt.setp(labels, rotation=0)

    # revert matplotlib params
    sns.reset_orig()

从csv文件中可以看出,它包含3个离散值:0,-1和1.我想要一个离散的图例而不是颜色条。将0标记为A,-1标记为B,标记为1标记为C.我该怎么做?

4 个答案:

答案 0 :(得分:11)

嗯,肯定有不止一种方法可以做到这一点。在这种情况下,只需要三种颜色,我会通过创建LinearSegmentedColormap而不是使用cubehelix_palette生成颜色来自己选择颜色。如果有足够的颜色可以保证使用cubehelix_palette,我会使用boundaries参数的cbar_kws选项在colormap上定义分段。无论哪种方式,都可以使用set_ticksset_ticklabels手动指定刻度线。

以下代码示例演示了LinearSegmentedColormap的手动创建,并包含有关如何使用cubehelix_palette指定边界的注释。

import matplotlib.pyplot as plt
import pandas
import seaborn.apionly as sns
from matplotlib.colors import LinearSegmentedColormap

sns.set(font_scale=0.8)
dataFrame = pandas.read_csv('LUH2_trans_matrix.csv').set_index(['Unnamed: 0'])

# For only three colors, it's easier to choose them yourself.
# If you still really want to generate a colormap with cubehelix_palette instead,
# add a cbar_kws={"boundaries": linspace(-1, 1, 4)} to the heatmap invocation
# to have it generate a discrete colorbar instead of a continous one.
myColors = ((0.8, 0.0, 0.0, 1.0), (0.0, 0.8, 0.0, 1.0), (0.0, 0.0, 0.8, 1.0))
cmap = LinearSegmentedColormap.from_list('Custom', myColors, len(myColors))

ax = sns.heatmap(dataFrame, cmap=cmap, linewidths=.5, linecolor='lightgray')

# Manually specify colorbar labelling after it's been generated
colorbar = ax.collections[0].colorbar
colorbar.set_ticks([-0.667, 0, 0.667])
colorbar.set_ticklabels(['B', 'A', 'C'])

# X - Y axis labels
ax.set_ylabel('FROM')
ax.set_xlabel('TO')

# Only y-axis labels need their rotation set, x-axis labels already have a rotation of 0
_, labels = plt.yticks()
plt.setp(labels, rotation=0)

plt.show()

Heatmap using red, green, and blue as colors with a discrete colorbar

答案 1 :(得分:5)

如果您使用import pandas import matplotlib.pyplot as plt import seaborn as sns from matplotlib.colors import ListedColormap # Read in csv file df_trans = pandas.read_csv('LUH2_trans_matrix.csv') sns.set(font_scale=0.8) # cmap is now a list of colors cmap = sns.cubehelix_palette(start=2.8, rot=.1, light=0.9, n_colors=3) df_trans = df_trans.set_index(['Unnamed: 0']) # Create two appropriately sized subplots grid_kws = {'width_ratios': (0.9, 0.03), 'wspace': 0.18} fig, (ax, cbar_ax) = plt.subplots(1, 2, gridspec_kw=grid_kws) ax = sns.heatmap(df_trans, ax=ax, cbar_ax=cbar_ax, cmap=ListedColormap(cmap), linewidths=.5, linecolor='lightgray', cbar_kws={'orientation': 'vertical'}) # Customize tick marks and positions cbar_ax.set_yticklabels(['B', 'A', 'C']) cbar_ax.yaxis.set_ticks([ 0.16666667, 0.5, 0.83333333]) # X - Y axis labels ax.set_ylabel('FROM') ax.set_xlabel('TO') # Rotate tick labels locs, labels = plt.xticks() plt.setp(labels, rotation=0) locs, labels = plt.yticks() plt.setp(labels, rotation=0) ,我发现seaborn中的离散色条更容易创建。无需定义自己的功能,只需添加几行即可自定义轴。

StringFormat

enter image description here

答案 2 :(得分:2)

@Fabio Lamanna提供的链接是一个很好的开始。

从那里,您仍然希望在正确的位置设置彩条标签,并使用与您的数据对应的刻度标签。

假设数据中的等级间隔相等,这会产生一个漂亮的离散颜色条:

基本上,这取决于关闭seaborn colorbar并用自己的离散色条替换它。

enter image description here

import pandas
import seaborn.apionly as sns
import matplotlib.pyplot as plt
import numpy as np
import matplotlib

def cmap_discretize(cmap, N):
    """Return a discrete colormap from the continuous colormap cmap.

        cmap: colormap instance, eg. cm.jet. 
        N: number of colors.

    Example
        x = resize(arange(100), (5,100))
        djet = cmap_discretize(cm.jet, 5)
        imshow(x, cmap=djet)
    """

    if type(cmap) == str:
        cmap = plt.get_cmap(cmap)
    colors_i = np.concatenate((np.linspace(0, 1., N), (0.,0.,0.,0.)))
    colors_rgba = cmap(colors_i)
    indices = np.linspace(0, 1., N+1)
    cdict = {}
    for ki,key in enumerate(('red','green','blue')):
        cdict[key] = [ (indices[i], colors_rgba[i-1,ki], colors_rgba[i,ki]) for i in xrange(N+1) ]
    # Return colormap object.
    return matplotlib.colors.LinearSegmentedColormap(cmap.name + "_%d"%N, cdict, 1024)

def colorbar_index(ncolors, cmap, data):

    """Put the colorbar labels in the correct positions
        using uique levels of data as tickLabels
    """

    cmap = cmap_discretize(cmap, ncolors)
    mappable = matplotlib.cm.ScalarMappable(cmap=cmap)
    mappable.set_array([])
    mappable.set_clim(-0.5, ncolors+0.5)
    colorbar = plt.colorbar(mappable)
    colorbar.set_ticks(np.linspace(0, ncolors, ncolors))
    colorbar.set_ticklabels(np.unique(data))


# Read in csv file
df_trans = pandas.read_csv('d:/LUH2_trans_matrix.csv')

sns.set(font_scale=0.8)
cmap = sns.cubehelix_palette(n_colors=3,start=2.8, rot=.1, light=0.9, as_cmap=True)
cmap.set_under('gray')  # 0 values in activity matrix are shown in gray (inactive transitions)
df_trans = df_trans.set_index(['Unnamed: 0'])

N = df_trans.max().max() - df_trans.min().min() + 1

f, ax = plt.subplots()
ax = sns.heatmap(df_trans, cmap=cmap, linewidths=.5, linecolor='lightgray',cbar=False)
colorbar_index(ncolors=N, cmap=cmap,data=df_trans)    

# X - Y axis labels
ax.set_ylabel('FROM')
ax.set_xlabel('TO')

# Rotate tick labels
locs, labels = plt.xticks()
plt.setp(labels, rotation=0)
locs, labels = plt.yticks()
plt.setp(labels, rotation=0)

# revert matplotlib params
sns.reset_orig()

herehere

中回收和改编的零碎碎片

答案 3 :(得分:1)

这是一个基于其他答案的简单解决方案,该答案概括了3个以上的类别,并使用字典(vmap)来定义标签。

import seaborn as sns
import numpy as np

# This just makes some sample 2D data and a corresponding vmap dict with labels for the values in the data
data = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
vmap = {i: chr(65 + i) for i in range(len(np.ravel(data)))}
n = len(vmap)

print(vmap)

cmap = sns.color_palette("deep", n)
ax = sns.heatmap(data, cmap=cmap)

# Get the colorbar object from the Seaborn heatmap
colorbar = ax.collections[0].colorbar
# The list comprehension calculates the positions to place the labels to be evenly distributed across the colorbar
r = colorbar.vmax - colorbar.vmin
colorbar.set_ticks([colorbar.vmin + 0.5 * r / (n) + r * i / (n) for i in range(n)])
colorbar.set_ticklabels(list(vmap.values()))

enter image description here