2016-05-26 10 views
8

К сожалению, я не нашел решение самостоятельно. Как создать Manhattan plot в python, используя, например, matplotlib/pandas. Проблема в том, что на этих графиках ось х дискретна.Как создать манхэттенский сюжет с matplotlib в python?

from pandas import DataFrame 
from scipy.stats import uniform 
from scipy.stats import randint 
import numpy as np 

# some sample data 
df = DataFrame({'gene' : ['gene-%i' % i for i in np.arange(1000)], 
'pvalue' : uniform.rvs(size=1000), 
'chromosome' : ['ch-%i' % i for i in randint.rvs(0,12,size=1000)]}) 

# -log_10(pvalue) 
df['minuslog10pvalue'] = -np.log10(df.pvalue) 
df = df.sort_values('chromosome') 

# How to plot gene vs. -log10(pvalue) and colour it by chromosome? 
+0

Вы можете только толково сюжет числовых данных, а не строки. Как действительно выглядят x-данные? –

+0

Манхэттенские сюжеты очень распространены в генетике, и они действительно очень разумны - или пусть говорят: информативные - для генетиков. X-data - это просто имена (да, строки) SNP-имен. (Может быть, я должен был бы назвать SNP x-data, а не гены в этом примере.) –

+0

Я не сказал, что thazt Манхэттенские сюжеты неразумны, я сказал, что это неправдоподобно значимо строить строки против числовых данных. Вы должны каким-то образом преобразовать свои имена в числа или просто использовать свой индекс. Я приведу небольшой пример использования искусственных данных в качестве ответа ниже. –

ответ

8

Вы можете использовать что-то вроде этого:

from pandas import DataFrame 
from scipy.stats import uniform 
from scipy.stats import randint 
import numpy as np 
import matplotlib.pyplot as plt 

# some sample data 
df = DataFrame({'gene' : ['gene-%i' % i for i in np.arange(10000)], 
'pvalue' : uniform.rvs(size=10000), 
'chromosome' : ['ch-%i' % i for i in randint.rvs(0,12,size=10000)]}) 

# -log_10(pvalue) 
df['minuslog10pvalue'] = -np.log10(df.pvalue) 
df.chromosome = df.chromosome.astype('category') 
df.chromosome = df.chromosome.cat.set_categories(['ch-%i' % i for i in range(12)], ordered=True) 
df = df.sort_values('chromosome') 

# How to plot gene vs. -log10(pvalue) and colour it by chromosome? 
df['ind'] = range(len(df)) 
df_grouped = df.groupby(('chromosome')) 

fig = plt.figure() 
ax = fig.add_subplot(111) 
colors = ['red','green','blue', 'yellow'] 
x_labels = [] 
x_labels_pos = [] 
for num, (name, group) in enumerate(df_grouped): 
    group.plot(kind='scatter', x='ind', y='minuslog10pvalue',color=colors[num % len(colors)], ax=ax) 
    x_labels.append(name) 
    x_labels_pos.append((group['ind'].iloc[-1] - (group['ind'].iloc[-1] - group['ind'].iloc[0])/2)) 
ax.set_xticks(x_labels_pos) 
ax.set_xticklabels(x_labels) 
ax.set_xlim([0, len(df)]) 
ax.set_ylim([0, 3.5]) 
ax.set_xlabel('Chromosome') 

Я только что создал дополнительный столбец индекса работает, чтобы иметь контроль над х метки местоположения.

enter image description here

+0

Я добавил следующие две строки перед сортировкой значений по хромосоме: 'df.chromosome = df.chromosome.astype (' category '); df.chromosome = df.chromosome.cat.set_categories (['ch-% i'% i для i в диапазоне (12)], упорядоченный = True) '. Это даст правильный порядок хромосом по оси x и позволит в конце появиться хромосомы X и Y (не в примере). Может быть, вы можете обновить свой пример? Благодаря! –

+0

Это хорошо работает, когда значение x является индексом, который вы назначаете каждой модели гена (который отвечает на вопрос так +1), но как насчет того, когда ваше значение x на самом деле представляет собой набор геномных координат, представленных в виде целых чисел. В этом случае нет никакой гарантии, что целые числа будут последовательными или уникальными, поскольку они находятся в вашем примере с индексами. Когда я заменяю индексы геномными координатами, все мои хромосомы перекрываются, а не размещаются бок о бок. – Malonge

7
import matplotlib.pyplot als plt 
from numpy.random import randn, random_sample 

g = random_sample(int(1e5))*10 # uniform random values between 0 and 10 
p = abs(randn(int(1e5))) # abs of normally distributed data 

""" 
plot g vs p in groups with different colors 
colors are cycled automatically by matplotlib 
use another colormap or define own colors for a different cycle 
""" 
for i in range(1,11): 
    plt.plot(g[abs(g-i)<1], p[abs(g-i)<1], ls='', marker='.') 

plt.show() 

Example of a manhattan style plot

Вы также можете проверить this script, который, кажется, предлагает законченное решение вашей проблемы.

+0

Ницца! Я все еще новичок в вызове функции plot внутри цикла. Просто не подумал бы об этом. Как бы вы могли добавить ниже каждого цветного столбца имя уважаемой хромосомы? Каждый столбец имеет разную ширину, так как каждая хромосома имеет разную длину. См. Пример на странице wikipedia (https://upload.wikimedia.org/wikipedia/commons/1/12/Manhattan_Plot.png). –

+0

В matplotlib вы можете установить свойства метки для xaxis и даже предоставить свои собственные строки для печати вместо числовых меток ... Подождите, теперь я понимаю. Вы действительно хотите построить хромосому по сравнению с pvalue, а не с геном. Но coor в основном также является просто номером хромосомы. Где входит номер гена? –

+0

То, что я еще не понимаю, - это то, как данные хромосомы должны распределяться по оси xaxis, потому что она, как вы сказали, дискретна. –