使用离散变量的二维离散彩色图

2D discrete colour plot using discrete variables

我正在寻找一种方法来以人类可读的格式绘制一些数据。我有来自模拟的数据,其中包含帧号、蛋白质残基数和蛋白质二级结构状态。帧数为整数,二级结构状态为字符串。例如:

0 1 2 3 4 5 6 7 8 9 10

1 'H' 'H' 'H' '0' 'H' '0' 'H' 'H' 'H' 'b' 'H' 'H' 'S'
2 'H' 'H' 'H' 'H' 'H' 'S' 'H' '0' 'b' 'H' 'H' 'H' 'H'

第 0 列包含帧编号,其余列对应于残基编号的状态(即第 1 帧的第 6 号残基的状态为“0”,第 2 帧为 'S' ).

我想生成帧号与残基号的二维图,根据 'Struc' 列中给出的字符串绘制特定颜色。最好手动控制给字符串的颜色(以避免相似的颜色)。

任何人都可以告诉我任何特定的 modules/submodules 可以让我这样做吗?

注意:这是针对大型数据集,文件可能达到 2000 帧超过 1000 个残基,因此需要计算效率。我也不反对重新格式化数据,它应该使绘图 easier/possible/faster.

下面的例子怎么样:

  1. 您首先定义数据(或者您将从文件中读取这些数据)。
  2. 为单个值定义颜色映射(参见下面的 colormapcolor documentation of matplotlib
  3. 一个函数会将这些letters/values映射到一个数字,将其视为一个索引。相同的索引将用于颜色访问
  4. 使用最近邻插值法和提供的颜色绘制图像

我的建议:

import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap

def toImage(frames, colormap):
    keys = list(colormap.keys())
    colors = [colormap[key] for key in keys]

    image = [[keys.index(val) for val in row[1:]] for row in frames]
    return image, colors

frames = [[0, 'H', 'H', 'H', '0', 'H', '0', 'H', 'H', 'H', 'b', 'H', 'H', 'S'],
          [1, 'H', 'H', 'H', 'H', 'H', 'S', 'H', '0', 'b', 'H', 'H', 'H', 'H']]

colormap = {'H': 'red',
            '0': 'green', 
            'S': '#4eefff',
            'b': 'b'}

image, colors = toImage(frames, colormap)

plt.imshow(image, cmap = ListedColormap(colors), interpolation = 'nearest')
plt.show()

当然,还有很多需要调整的地方(例如,我完全省略了帧数,适当地调整 y-ticks,...)但它应该能让你开始

这是使用 Seaborn heatmap 的替代方法,可能更适合大型数据集。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
import seaborn as sns

# create dataset
residue_state_options = ['H', '0', 'S', 'b']
residue_state_arr = np.random.choice(residue_state_options,
                                     (100, 100), p=[0.7, 0.1, 0.1, 0.1])

df = pd.DataFrame(residue_state_arr)

# map dataset to numbers
residue_state_map = {'H': 0, '0': 1, 'S': 2, 'b': 3}
df.replace(residue_state_map, inplace=True)

ax = sns.heatmap(df)

对于稍微复杂一点的情节,加上对颜色的控制,你可以去掉最后一行,而不是做类似

的事情
colors = ['#edf8fb', '#b2e2e2', '#66c2a4', '#238b45']

grid_kws = {'height_ratios': (0.9, 0.05), 'hspace': 0.2}
fig, (ax, cbar_ax) = plt.subplots(2, gridspec_kw=grid_kws)
ax = sns.heatmap(df, ax=ax, cbar_ax=cbar_ax, cmap=ListedColormap(colors),
                 xticklabels=False, yticklabels=False,
                 cbar_kws={'orientation': 'horizontal'})

cbar_ax.set_xticklabels(residue_state_options)
cbar_ax.xaxis.set_ticks([0.125,  0.375,  0.625,  0.875])

实现这个情节。