Вот как я это сделал, если в будущем у кого-то возникнет похожая проблема.
Получите оси, над которыми вы работаете, с помощью 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)
Пример вывода приведен здесь: 