создание собственной легенды / руководства по альфа-уровню - PullRequest
0 голосов
/ 01 октября 2019

Я пытаюсь построить уровни экспрессии генов. По существу для каждого гена я рисую «pyplot.arrow» и окрашиваю его альфа = expression_level. Уровни выражения нормализованы до значений от 0 до 1. Теперь я хочу создать легенду на основе альфы, которая показывает, какой уровень альфы соответствует какому уровню выражения.

Вот пример кода для созданияграфик для нескольких генов:

genes = pd.DataFrame({'start': [52285155, 52391508, 52776238], 'end': [52390609, 52405893, 52782964], 'name': ['ITGA2', 'MOCS2', 'FST'], 'expression': [8.48, 12.3, 3.83], 'strand' : ['+', '-', '+']})
genes = genes.sort_values(by = ["start"])
plt.xlim(genes['start'].min()- 5000, genes['end'].max() + 5000)

#this is to assign different y values so I don't draw them on top of each other. Not important for this question.
gene_count = genes.shape[0]
heights = max(1 / gene_count, 0.33)
height_start = heights / 2
heights = list(np.arange(height_start, height_start + heights * gene_count, heights) % 1)
genes['y'] = heights

# this is to normalize expression values to [0-1]
colors = genes["expression"]
genes["expression_color"] = (colors - colors.min())/(colors.max()-colors.min())  

genes["width"] = genes["end"] - genes["start"]
for g in range(genes.shape[0]):
        g = genes.iloc[g]
        if g.strand == "+":
            plt.arrow(g.start, g.y, g.width, 0, length_includes_head = True, width = 0.1, head_width = 0.2, head_length = g.width*0.05, alpha = g.expression_color)
        else:
            plt.arrow(g.end, g.y, -g.width, 0, length_includes_head = True, width = 0.1, head_width = 0.2, head_length = g.width*0.05, alpha = g.expression_color)
        plt.text(x = (g.start + g.end)/2, y = g.y, s = g["name"], size = 16, horizontalalignment='center')  

Я хотел бы добавить небольшую цветовую схему, например легенду о прозрачности, которая показывает, что альфа = 0 соответствует 3,83 (минимальное выражение до масштабирования), альфа = 1 соответствует 12,3(максимальное выражение до масштабирования).

1 Ответ

0 голосов
/ 02 октября 2019

Вот как я это сделал, если в будущем у кого-то возникнет похожая проблема.

Получите оси, над которыми вы работаете, с помощью plt.gca (), затем создайте другие оси, которые будут построены внутри него. используя axes.inset_axes (). вместо использования альфа-канала для раскраски различных значений выражения используйте цветовую карту matplotlib, например "YlOrRd" (я установил альфа-канал на 0,8, чтобы обеспечить прозрачность при наличии совпадений между местоположениями генов и / или легендой. Я также заменил предыдущую нормализациюв [0,1] с помощью функции matplotlib.colors.Normalize (вы также можете использовать matplotlib.colors.LogNorm).

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

def add_legend(ax, genes):
    ax.patch.set_alpha(0.5)
    exp_max = genes["log10exp"].max()
    exp_min = genes["log10exp"].min()
    print(exp_max, exp_min)
    gradient = np.linspace(exp_min, exp_max, 256)
    gradient = gradient.reshape(1,256)
    ax.imshow(gradient, aspect='auto', cmap="YlOrRd", alpha = 0.8)
    #ax.set_xticks([])
    ax.set_xticks([0, 128, 256])
    ax.set_xticklabels(["{:0.2f}".format(float(exp_min)), "{:0.2f}".format(exp_max/2), "{:0.2f}".format(exp_max)])
    ax.tick_params(axis="x",direction="in", pad=-10)
    #ax.xaxis.set_ticks_position('top')
    ax.set_yticks([])
    ax.set_xlabel("log10(expression+1)")

genes = pd.DataFrame({'start': [52285155, 52391508, 52776238], 'end': [52390609, 52405893, 52782964], 'name': ['ITGA2', 'MOCS2', 'FST'], 'expression': [8.48, 78.3, 3.83], 'strand' : ['+', '-', '+']})
genes = genes.sort_values(by = ["start"])
plt.xlim(genes['start'].min()- 5000, genes['end'].max() + 5000)
#this is to assign different y values so I don't draw them on top of each other. Not important for this question.
gene_count = genes.shape[0]
heights = max(1 / gene_count, 0.33)
height_start = heights / 2
heights = list(np.arange(height_start, height_start + heights * gene_count, heights) % 1)
genes['y'] = heights
cmap = matplotlib.cm.get_cmap('YlOrRd')

# this is to normalize expression values to [0-1]
genes['log10exp'] = np.log10(genes["expression"] + 1)
norm = matplotlib.colors.Normalize(vmin=colors.min(), vmax=colors.max())
genes["expression_color"] = genes.log10exp.apply(norm)


genes["width"] = genes["end"] - genes["start"]
for g in range(genes.shape[0]):
        g = genes.iloc[g]
        if g.strand == "+":
            plt.arrow(g.start, g.y, g.width, 0, length_includes_head = True, width = 0.1, head_width = 0.2, head_length = g.width*0.05, color = cmap(g.expression_color), alpha = 0.8)
        else:
            plt.arrow(g.end, g.y, -g.width, 0, length_includes_head = True, width = 0.1, head_width = 0.2, head_length = g.width*0.05, color = cmap(g.expression_color), alpha = 0.8)
        plt.text(x = (g.start + g.end)/2, y = g.y, s = g["name"], size = 16, horizontalalignment='center')   
ax = plt.gca()
ax2 = ax.inset_axes([0.88,0.88,0.1,0.1])
add_legend(ax2, genes)

Пример вывода приведен здесь: enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...