.
Example::
- result = get_parallel_plot(data, identifier='parallel plot', args={'group':'group', 'zscore':True, 'color':'blue', 'title':'Parallel Plot'})
+ result = get_parallel_plot(data,
+ identifier='parallel plot',
+ args={'group':'group',
+ 'zscore':True,
+ 'color':'blue',
+ 'title':'Parallel Plot'}
+ )
"""
fig = None
- if 'group' in args:
- group = args['group']
- if 'zscore' in args:
- if args['zscore']:
+ if "group" in args:
+ group = args["group"]
+ if "zscore" in args:
+ if args["zscore"]:
data = data.set_index(group).apply(zscore)
data = data.reset_index()
- color = '#de77ae'
- if 'color' in args:
- color = args['color']
+ color = "#de77ae"
+ if "color" in args:
+ color = args["color"]
group_values = data.groupby(group).mean()
min_val = group_values._get_numeric_data().min().min()
max_val = group_values._get_numeric_data().max().max()
@@ -1860,27 +2470,25 @@ def get_parallel_plot(data, identifier, args):
dim = dict(label=i, range=[min_val, max_val], values=values)
dims.append(dim)
- fig_data = [
- go.Parcoords(
- line = dict(color = color),
- dimensions = dims)
- ]
+ fig_data = [go.Parcoords(line=dict(color=color), dimensions=dims)]
layout = go.Layout(
- title=args['title'],
- annotations= [dict(xref='paper', yref='paper', showarrow=False, text='')],
- template='plotly_white'
+ title=args["title"],
+ annotations=[dict(xref="paper", yref="paper", showarrow=False, text="")],
+ template="plotly_white",
)
- fig = dict(data = fig_data, layout = layout)
+ fig = dict(data=fig_data, layout=layout)
return dcc.Graph(id=identifier, figure=fig)
+
def get_parallel_coord_plot(data, identifier, args):
- color = args['color']
- labels = {c:c for c in data.columns if c != color}
+ color = args["color"]
+ labels = {c: c for c in data.columns if c != color}
fig = px.parallel_coordinates(data, color=color, labels=labels)
return fig
+
def get_WGCNAPlots(data, identifier):
"""
Takes data from runWGCNA function and builds WGCNA plots.
@@ -1893,43 +2501,157 @@ def get_WGCNAPlots(data, identifier):
data = tuple(data[k] for k in data)
if data is not None:
- dissTOM, moduleColors, Features_per_Module, MEs,\
- moduleTraitCor, textMatrix, METDiss, METcor = data
+ (
+ dissTOM,
+ moduleColors,
+ Features_per_Module,
+ MEs,
+ moduleTraitCor,
+ textMatrix,
+ METDiss,
+ METcor,
+ ) = data
plots = []
- plots.append(wgcnaFigures.plot_complex_dendrogram(dissTOM, moduleColors, title='Co-expression: dendrogram and module colors', dendro_labels=dissTOM.columns, distfun=None, linkagefun='ward', hang=0.1, subplot='module colors', col_annotation=True, width=1000, height=800))
- plots.append(get_table(Features_per_Module, identifier='', args={'title':'Proteins/Genes module color', 'colors': ('#C2D4FF','#F5F8FF'), 'cols': None, 'rows': None}))
- plots.append(wgcnaFigures.plot_labeled_heatmap(moduleTraitCor, textMatrix, title='Module-Clinical variable relationships', colorscale=[[0,'#67a9cf'],[0.5,'#f7f7f7'],[1,'#ef8a62']], row_annotation=True, width=1000, height=800))
- dendro_tree = wgcnaAnalysis.get_dendrogram(METDiss, METDiss.index, distfun=None, linkagefun='ward', div_clusters=False)
+ plots.append(
+ wgcna.plot_complex_dendrogram(
+ dissTOM,
+ moduleColors,
+ title="Co-expression: dendrogram and module colors",
+ dendro_labels=dissTOM.columns,
+ distfun=None,
+ linkagefun="ward",
+ hang=0.1,
+ subplot="module colors",
+ col_annotation=True,
+ width=1000,
+ height=800,
+ )
+ )
+ plots.append(
+ get_table(
+ Features_per_Module,
+ identifier="",
+ args={
+ "title": "Proteins/Genes module color",
+ "colors": ("#C2D4FF", "#F5F8FF"),
+ "cols": None,
+ "rows": None,
+ },
+ )
+ )
+ plots.append(
+ wgcna.plot_labeled_heatmap(
+ moduleTraitCor,
+ textMatrix,
+ title="Module-Clinical variable relationships",
+ colorscale=[[0, "#67a9cf"], [0.5, "#f7f7f7"], [1, "#ef8a62"]],
+ row_annotation=True,
+ width=1000,
+ height=800,
+ )
+ )
+ dendro_tree = wgcna_analysis.get_dendrogram(
+ METDiss, METDiss.index, distfun=None, linkagefun="ward", div_clusters=False
+ )
if dendro_tree is not None:
- dendrogram = Dendrogram.plot_dendrogram(dendro_tree, hang=0.9, cutoff_line=False)
+ dendrogram_ = dendrogram.plot_dendrogram(
+ dendro_tree, hang=0.9, cutoff_line=False
+ )
- layout = go.Layout(width=900, height=900, showlegend=False, title='',
- xaxis=dict(domain=[0, 1], range=[np.min(dendrogram['layout']['xaxis']['tickvals']) - 6, np.max(dendrogram['layout']['xaxis']['tickvals'])+4], showgrid=False,
- zeroline=True, ticks='', automargin=True, anchor='y'),
- yaxis=dict(domain=[0.7, 1], autorange=True, showgrid=False, zeroline=False, ticks='outside', title='Height', automargin=True, anchor='x'),
- xaxis2=dict(domain=[0, 1], autorange=True, showgrid=True, zeroline=False, ticks='', showticklabels=False, automargin=True, anchor='y2'),
- yaxis2=dict(domain=[0, 0.64], autorange=True, showgrid=False, zeroline=False, automargin=True, anchor='x2'))
+ layout = go.Layout(
+ width=900,
+ height=900,
+ showlegend=False,
+ title="",
+ xaxis=dict(
+ domain=[0, 1],
+ range=[
+ np.min(dendrogram_["layout"]["xaxis"]["tickvals"]) - 6,
+ np.max(dendrogram_["layout"]["xaxis"]["tickvals"]) + 4,
+ ],
+ showgrid=False,
+ zeroline=True,
+ ticks="",
+ automargin=True,
+ anchor="y",
+ ),
+ yaxis=dict(
+ domain=[0.7, 1],
+ autorange=True,
+ showgrid=False,
+ zeroline=False,
+ ticks="outside",
+ title="Height",
+ automargin=True,
+ anchor="x",
+ ),
+ xaxis2=dict(
+ domain=[0, 1],
+ autorange=True,
+ showgrid=True,
+ zeroline=False,
+ ticks="",
+ showticklabels=False,
+ automargin=True,
+ anchor="y2",
+ ),
+ yaxis2=dict(
+ domain=[0, 0.64],
+ autorange=True,
+ showgrid=False,
+ zeroline=False,
+ automargin=True,
+ anchor="x2",
+ ),
+ )
- if all(list(METcor.columns.map(lambda x: METcor[x].between(-1, 1, inclusive=True).all()))) != True:
- df = wgcnaAnalysis.get_percentiles_heatmap(METcor, dendro_tree, bydendro=True, bycols=False).T
+ if not (
+ all(
+ list(
+ METcor.columns.map(
+ lambda x: METcor[x].between(-1, 1, inclusive=True).all()
+ )
+ )
+ )
+ ):
+ df = wgcna_analysis.get_percentiles_heatmap(
+ METcor, dendro_tree, bydendro=True, bycols=False
+ ).T
else:
- df = wgcnaAnalysis.df_sort_by_dendrogram(wgcnaAnalysis.df_sort_by_dendrogram(METcor, dendro_tree).T, dendro_tree)
-
- heatmap = wgcnaFigures.get_heatmap(df, colorscale=[[0,'#67a9cf'],[0.5,'#f7f7f7'],[1,'#ef8a62']], color_missing=False)
+ df = wgcna_analysis.df_sort_by_dendrogram(
+ wgcna_analysis.df_sort_by_dendrogram(METcor, dendro_tree).T,
+ dendro_tree,
+ )
+
+ heatmap = wgcna.get_heatmap(
+ df,
+ colorscale=[[0, "#67a9cf"], [0.5, "#f7f7f7"], [1, "#ef8a62"]],
+ color_missing=False,
+ )
figure = tools.make_subplots(rows=2, cols=1, print_grid=False)
- for i in list(dendrogram['data']):
+ for i in list(dendrogram_["data"]):
figure.append_trace(i, 1, 1)
- for j in list(heatmap['data']):
+ for j in list(heatmap["data"]):
figure.append_trace(j, 2, 1)
- figure['layout'] = layout
- figure['layout']['template'] = 'plotly_white'
- figure['layout'].update({'xaxis':dict(domain=[0, 1], ticks='', showticklabels=False, anchor='y'),
- 'xaxis2':dict(domain=[0, 1], ticks='', showticklabels=True, anchor='y2'),
- 'yaxis':dict(domain=[0.635, 1], anchor='x'),
- 'yaxis2':dict(domain=[0., 0.635], ticks='', showticklabels=True, anchor='x2')})
+ figure["layout"] = layout
+ figure["layout"]["template"] = "plotly_white"
+ figure["layout"].update(
+ {
+ "xaxis": dict(
+ domain=[0, 1], ticks="", showticklabels=False, anchor="y"
+ ),
+ "xaxis2": dict(
+ domain=[0, 1], ticks="", showticklabels=True, anchor="y2"
+ ),
+ "yaxis": dict(domain=[0.635, 1], anchor="x"),
+ "yaxis2": dict(
+ domain=[0.0, 0.635], ticks="", showticklabels=True, anchor="x2"
+ ),
+ }
+ )
plots.append(figure)
@@ -1938,7 +2660,7 @@ def get_WGCNAPlots(data, identifier):
if isinstance(j, html.Div):
graphs.append(j)
else:
- graphs.append(dcc.Graph(id=identifier+'_'+str(i), figure=j))
+ graphs.append(dcc.Graph(id=identifier + "_" + str(i), figure=j))
return graphs
@@ -1953,26 +2675,49 @@ def getMapperFigure(data, identifier, title):
:param str title: plot title.
:return: plotly FigureWidget within
.
"""
- pl_brewer = [[0.0, '#67001f'],
- [0.1, '#b2182b'],
- [0.2, '#d6604d'],
- [0.3, '#f4a582'],
- [0.4, '#fddbc7'],
- [0.5, '#000000'],
- [0.6, '#d1e5f0'],
- [0.7, '#92c5de'],
- [0.8, '#4393c3'],
- [0.9, '#2166ac'],
- [1.0, '#053061']]
- figure = plotlyviz.plotlyviz(data, title=title, colorscale=pl_brewer, color_function_name="Group",factor_size=7, edge_linewidth=2.5,
- node_linecolor="rgb(200,200,200)", width=1200, height=1200, bgcolor="rgba(240, 240, 240, 0.95)",
- left=50, bottom=50, summary_height=300, summary_width=400, summary_left=20, summary_right=20,
- hist_left=25, hist_right=25, member_textbox_width=800)
- return dcc.Graph(id = identifier, figure=figure)
+ from kmapper import plotlyviz
+
+ pl_brewer = [
+ [0.0, "#67001f"],
+ [0.1, "#b2182b"],
+ [0.2, "#d6604d"],
+ [0.3, "#f4a582"],
+ [0.4, "#fddbc7"],
+ [0.5, "#000000"],
+ [0.6, "#d1e5f0"],
+ [0.7, "#92c5de"],
+ [0.8, "#4393c3"],
+ [0.9, "#2166ac"],
+ [1.0, "#053061"],
+ ]
+ figure = plotlyviz.plotlyviz(
+ data,
+ title=title,
+ colorscale=pl_brewer,
+ color_function_name="Group",
+ factor_size=7,
+ edge_linewidth=2.5,
+ node_linecolor="rgb(200,200,200)",
+ width=1200,
+ height=1200,
+ bgcolor="rgba(240, 240, 240, 0.95)",
+ left=50,
+ bottom=50,
+ summary_height=300,
+ summary_width=400,
+ summary_left=20,
+ summary_right=20,
+ hist_left=25,
+ hist_right=25,
+ member_textbox_width=800,
+ )
+ return dcc.Graph(id=identifier, figure=figure)
+
def get_2_venn_diagram(data, identifier, cond1, cond2, args):
"""
- This function extracts the exlusive features in cond1 and cond2 and their common features, and build a two-circle venn diagram.
+ This function extracts the exlusive features in cond1 and cond2 and their common features,
+ and build a two-circle venn diagram.
:param data: pandas dataframe with features as rows and group identifiers as columns.
:param str identifier: id used to identify the div where the figure will be generated.
@@ -1986,17 +2731,31 @@ def get_2_venn_diagram(data, identifier, cond1, cond2, args):
Example::
- result = get_2_venn_diagram(data, identifier='venn2', cond1='group1', cond2='group2', args={'color':{'group1':'blue', 'group2':'red'}, \
- 'title':'Two-circle Venn diagram'})
+ result = get_2_venn_diagram(data,
+ identifier='venn2',
+ cond1='group1',
+ cond2='group2',
+ args={'color':{'group1':'blue', 'group2':'red'},
+ 'title':'Two-circle Venn diagram'}
+ )
"""
figure = {}
figure["data"] = []
- unique1 = len(set(data[cond1].dropna().index).difference(data[cond2].dropna().index))#/total
- unique2 = len(set(data[cond2].dropna().index).difference(data[cond1].dropna().index))#/total
- intersection = len(set(data[cond1].dropna().index).intersection(data[cond2].dropna().index))#/total
+ unique1 = len(
+ set(data[cond1].dropna().index).difference(data[cond2].dropna().index)
+ ) # /total
+ unique2 = len(
+ set(data[cond2].dropna().index).difference(data[cond1].dropna().index)
+ ) # /total
+ intersection = len(
+ set(data[cond1].dropna().index).intersection(data[cond2].dropna().index)
+ ) # /total
+
+ return plot_2_venn_diagram(
+ cond1, cond2, unique1, unique2, intersection, identifier, args
+ )
- return plot_2_venn_diagram(cond1, cond2, unique1, unique2, intersection, identifier, args)
def plot_2_venn_diagram(cond1, cond2, unique1, unique2, intersection, identifier, args):
"""
@@ -2016,92 +2775,110 @@ def plot_2_venn_diagram(cond1, cond2, unique1, unique2, intersection, identifier
Example::
- result = plot_2_venn_diagram(cond1='group1', cond2='group2', unique1=10, unique2=15, intersection=8, identifier='vennplot', \
- args={'color':{'group1':'blue', 'group2':'red'}, 'title':'Two-circle Venn diagram'})
+ result = plot_2_venn_diagram(cond1='group1',
+ cond2='group2',
+ unique1=10,
+ unique2=15,
+ intersection=8,
+ identifier='vennplot',
+ args={'color':{'group1':'blue', 'group2':'red'},
+ 'title':'Two-circle Venn diagram'}
+ )
"""
figure = {}
figure["data"] = []
- figure["data"] = [go.Scattergl(
- x=[1, 1.75, 2.5],
- y=[1, 1, 1],
- text=[str(unique1), str(intersection), str(unique2)],
- mode='text',
- textfont=dict(
- color='black',
- size=14,
- family='Arial',
+ figure["data"] = [
+ go.Scattergl(
+ x=[1, 1.75, 2.5],
+ y=[1, 1, 1],
+ text=[str(unique1), str(intersection), str(unique2)],
+ mode="text",
+ textfont=dict(
+ color="black",
+ size=14,
+ family="Arial",
+ ),
)
- )]
-
- if 'colors' not in args:
- args['colors'] = {cond1:'#a6bddb', cond2:'#045a8d'}
+ ]
+ if "colors" not in args:
+ args["colors"] = {cond1: "#a6bddb", cond2: "#045a8d"}
figure["layout"] = {
- 'xaxis': {
- 'showticklabels': False,
- 'showgrid': False,
- 'zeroline': False,
+ "xaxis": {
+ "showticklabels": False,
+ "showgrid": False,
+ "zeroline": False,
},
- 'yaxis': {
- 'showticklabels': False,
- 'showgrid': False,
- 'zeroline': False,
+ "yaxis": {
+ "showticklabels": False,
+ "showgrid": False,
+ "zeroline": False,
},
- 'shapes': [
+ "shapes": [
{
- 'opacity': 0.3,
- 'xref': 'x',
- 'yref': 'y',
- 'fillcolor': args['colors'][cond1],
- 'x0': 0,
- 'y0': 0,
- 'x1': 2,
- 'y1': 2,
- 'type': 'circle',
- 'line': {
- 'color': args['colors'][cond1],
+ "opacity": 0.3,
+ "xref": "x",
+ "yref": "y",
+ "fillcolor": args["colors"][cond1],
+ "x0": 0,
+ "y0": 0,
+ "x1": 2,
+ "y1": 2,
+ "type": "circle",
+ "line": {
+ "color": args["colors"][cond1],
},
},
{
- 'opacity': 0.3,
- 'xref': 'x',
- 'yref': 'y',
- 'fillcolor': args['colors'][cond2],
- 'x0': 1.5,
- 'y0': 0,
- 'x1': 3.5,
- 'y1': 2,
- 'type': 'circle',
- 'line': {
- 'color': args['colors'][cond2],
+ "opacity": 0.3,
+ "xref": "x",
+ "yref": "y",
+ "fillcolor": args["colors"][cond2],
+ "x0": 1.5,
+ "y0": 0,
+ "x1": 3.5,
+ "y1": 2,
+ "type": "circle",
+ "line": {
+ "color": args["colors"][cond2],
},
- }
+ },
],
- 'margin': {
- 'l': 20,
- 'r': 20,
- 'b': 100
- },
- 'height': 600,
- 'width': 800,
- 'title':args['title'],
- "template":'plotly_white'
+ "margin": {"l": 20, "r": 20, "b": 100},
+ "height": 600,
+ "width": 800,
+ "title": args["title"],
+ "template": "plotly_white",
}
- return dcc.Graph(id = identifier, figure=figure)
+ return dcc.Graph(id=identifier, figure=figure)
+
-def get_wordcloud(data, identifier, args={'stopwords':[], 'max_words': 400, 'max_font_size': 100, 'width':700, 'height':700, 'margin': 1}):
+def get_wordcloud(
+ data,
+ identifier,
+ args={
+ "stopwords": [],
+ "max_words": 400,
+ "max_font_size": 100,
+ "width": 700,
+ "height": 700,
+ "margin": 1,
+ },
+):
"""
This function generates a Wordcloud based on the natural text in a pandas dataframe column.
- :param data: pandas dataframe with columns: 'PMID', 'abstract', 'authors', 'date', 'journal', 'keywords', 'title', 'url', 'Proteins', 'Diseases'.
+ :param data: pandas dataframe with columns: 'PMID', 'abstract', 'authors', 'date', 'journal',
+ 'keywords', 'title', 'url', 'Proteins', 'Diseases'.
:param str identifier: id used to identify the div where the figure will be generated.
:param dict args: see below.
:Arguments:
- * **text_col** (str) -- name of column containing the natural text used to generate the wordcloud.
+ * **text_col** (str) -- name of column containing the natural text used to \
+ generate the wordcloud.
* **stopwords** (list) -- list of words that will be eliminated.
* **max_words** (int) -- maximum number of words.
* **max_font_size** (int) -- maximum font size for the largest word.
@@ -2113,36 +2890,165 @@ def get_wordcloud(data, identifier, args={'stopwords':[], 'max_words': 400, 'max
Example::
- result = get_wordcloud(data, identifier='wordcloud', args={'stopwords':['BACKGROUND','CONCLUSION','RESULT','METHOD','CONCLUSIONS','RESULTS','METHODS'], \
- 'max_words': 400, 'max_font_size': 100, 'width':700, 'height':700, 'margin': 1})
+ result = get_wordcloud(data,
+ identifier='wordcloud',
+ args={'stopwords':['BACKGROUND',
+ 'CONCLUSION',
+ 'RESULT',
+ 'METHOD',
+ 'CONCLUSIONS',
+ 'RESULTS',
+ 'METHODS'],
+ 'max_words': 400,
+ 'max_font_size': 100,
+ 'width':700,
+ 'height':700,
+ 'margin': 1}
+ )
"""
- figure=None
+ figure = None
if data is not None:
- nltk.download('stopwords')
- sw = set(stopwords.words('english')).union(set(STOPWORDS))
- sw.update(['patient', 'protein', 'gene', 'proteins', 'genes', 'using', 'review',
- 'identified', 'identify', 'expression', 'role', 'functions', 'factors',
- 'cell', 'function', 'human', 'may', 'found', 'well', 'analysis', 'recent',
- 'data', 'include', 'including', 'specific', 'involve', 'study', 'information',
- 'studies', 'demonstrate', 'demonstrated', 'associated', 'show', 'Changes',
- 'showed', 'high', 'low', 'level', 'system', 'change', 'different', 'pathways',
- 'similar', 'several', 'many', 'factor', 'peptide', 'based', 'lead', 'processes',
- 'finding', 'pathway', 'process', 'disease', 'performed', 'p', 'p-value', 'model',
- 'value', 'line', 'mechanism', 'patients', 'mechanisms', 'known', 'increased', 'cells',
- 'decreased', 'involved', 'complex', 'levels', 'type', 'activity', 'new', 'contribute',
- 'approach', 'significant', 'significantly', 'propose', 'suggests', 'biological', 'suggest',
- 'lines', 'clinical', 'provide', 'tissue', 'number', 'via', 'important', 'co', 'profile',
- 'vitro', 'complexes', 'domain', 'signaling', 'induced', 'regulation', 'signature', 'dependent',
- 'diseases', 'vivo', 'promote', 'Thus', 'used', 'related', 'key', 'shown', 'first', 'one', 'two',
- 'research', 'pattern', 'major', 'novel', 'effect', 'affect', 'multiple', 'present', 'normal',
- 'Finally', 'signalling', 'Although', 'play', 'discuss', 'risk', 'association', 'underlying'])
- if 'stopwords' in args:
- sw = sw.union(args['stopwords'])
+ nltk.download("stopwords")
+ sw = set(stopwords.words("english")).union(set(STOPWORDS))
+ sw.update(
+ [
+ "patient",
+ "protein",
+ "gene",
+ "proteins",
+ "genes",
+ "using",
+ "review",
+ "identified",
+ "identify",
+ "expression",
+ "role",
+ "functions",
+ "factors",
+ "cell",
+ "function",
+ "human",
+ "may",
+ "found",
+ "well",
+ "analysis",
+ "recent",
+ "data",
+ "include",
+ "including",
+ "specific",
+ "involve",
+ "study",
+ "information",
+ "studies",
+ "demonstrate",
+ "demonstrated",
+ "associated",
+ "show",
+ "Changes",
+ "showed",
+ "high",
+ "low",
+ "level",
+ "system",
+ "change",
+ "different",
+ "pathways",
+ "similar",
+ "several",
+ "many",
+ "factor",
+ "peptide",
+ "based",
+ "lead",
+ "processes",
+ "finding",
+ "pathway",
+ "process",
+ "disease",
+ "performed",
+ "p",
+ "p-value",
+ "model",
+ "value",
+ "line",
+ "mechanism",
+ "patients",
+ "mechanisms",
+ "known",
+ "increased",
+ "cells",
+ "decreased",
+ "involved",
+ "complex",
+ "levels",
+ "type",
+ "activity",
+ "new",
+ "contribute",
+ "approach",
+ "significant",
+ "significantly",
+ "propose",
+ "suggests",
+ "biological",
+ "suggest",
+ "lines",
+ "clinical",
+ "provide",
+ "tissue",
+ "number",
+ "via",
+ "important",
+ "co",
+ "profile",
+ "vitro",
+ "complexes",
+ "domain",
+ "signaling",
+ "induced",
+ "regulation",
+ "signature",
+ "dependent",
+ "diseases",
+ "vivo",
+ "promote",
+ "Thus",
+ "used",
+ "related",
+ "key",
+ "shown",
+ "first",
+ "one",
+ "two",
+ "research",
+ "pattern",
+ "major",
+ "novel",
+ "effect",
+ "affect",
+ "multiple",
+ "present",
+ "normal",
+ "Finally",
+ "signalling",
+ "Although",
+ "play",
+ "discuss",
+ "risk",
+ "association",
+ "underlying",
+ ]
+ )
+ if "stopwords" in args:
+ sw = sw.union(args["stopwords"])
if isinstance(data, pd.DataFrame):
if not data.empty:
if "text_col" in args:
- text = ''.join(str(a) for a in data[args["text_col"]].unique().tolist())
+ text = "".join(
+ str(a) for a in data[args["text_col"]].unique().tolist()
+ )
else:
return None
else:
@@ -2150,19 +3056,21 @@ def get_wordcloud(data, identifier, args={'stopwords':[], 'max_words': 400, 'max
else:
text = data
- wc = WordCloud(stopwords = sw,
- max_words = args['max_words'],
- max_font_size = args['max_font_size'],
- background_color='white',
- margin=args['margin'])
+ wc = WordCloud(
+ stopwords=sw,
+ max_words=args["max_words"],
+ max_font_size=args["max_font_size"],
+ background_color="white",
+ margin=args["margin"],
+ )
wc.generate(text)
- word_list=[]
- freq_list=[]
- fontsize_list=[]
- position_list=[]
- orientation_list=[]
- color_list=[]
+ word_list = []
+ freq_list = []
+ fontsize_list = []
+ position_list = []
+ orientation_list = []
+ color_list = []
for (word, freq), fontsize, position, orientation, color in wc.layout_:
word_list.append(word)
@@ -2173,87 +3081,90 @@ def get_wordcloud(data, identifier, args={'stopwords':[], 'max_words': 400, 'max
color_list.append(color)
# get the positions
- x=[]
- y=[]
+ x = []
+ y = []
j = 0
for i in position_list:
- x.append(i[1]+fontsize_list[j]+10)
- y.append(i[0]+5)
+ x.append(i[1] + fontsize_list[j] + 10)
+ y.append(i[0] + 5)
j += 1
# get the relative occurence frequencies
new_freq_list = []
for i in freq_list:
- new_freq_list.append(i*70)
+ new_freq_list.append(i * 70)
new_freq_list
- trace = go.Scattergl(x=x,
- y=y,
- textfont = dict(size=new_freq_list,
- color=color_list),
- hoverinfo='text',
- hovertext=['{0} freq: {1}'.format(w, f) for w, f in zip(word_list, freq_list)],
- mode="text",
- text=word_list
- )
+ trace = go.Scattergl(
+ x=x,
+ y=y,
+ textfont=dict(size=new_freq_list, color=color_list),
+ hoverinfo="text",
+ hovertext=[
+ "{0} freq: {1}".format(w, f) for w, f in zip(word_list, freq_list)
+ ],
+ mode="text",
+ text=word_list,
+ )
layout = go.Layout(
- xaxis=dict(showgrid=False,
- showticklabels=False,
- zeroline=False,
- automargin=True),
- yaxis=dict(showgrid=False,
- showticklabels=False,
- zeroline=False,
- automargin=True),
- width=args['width'],
- height=args['height'],
- title=args['title'],
- annotations = [dict(xref='paper', yref='paper', showarrow=False, text='')],
- template='plotly_white'
- )
+ xaxis=dict(
+ showgrid=False, showticklabels=False, zeroline=False, automargin=True
+ ),
+ yaxis=dict(
+ showgrid=False, showticklabels=False, zeroline=False, automargin=True
+ ),
+ width=args["width"],
+ height=args["height"],
+ title=args["title"],
+ annotations=[dict(xref="paper", yref="paper", showarrow=False, text="")],
+ template="plotly_white",
+ )
figure = dict(data=[trace], layout=layout)
- return dcc.Graph(id = identifier, figure=figure)
+ return dcc.Graph(id=identifier, figure=figure)
def get_cytoscape_network(net, identifier, args):
"""
- This function creates a Cytoscpae network in dash. For more information visit https://dash.plot.ly/cytoscape.
+ This function creates a Cytoscpae network in dash.
- :param dict net: dictionary in which each element (key) is defined by a dictionary with 'id' and 'label' \
- (if it is a node) or 'source', 'target' and 'label' (if it is an edge).
+ For more information visit https://dash.plot.ly/cytoscape.
+
+ :param dict net: dictionary in which each element (key) is defined by a dictionary with 'id'
+ and 'label' (if it is a node) or 'source', 'target' and 'label' (if it is an edge).
:param str identifier: is the id used to identify the div where the figure will be generated.
:param dict args: see below.
:Arguments:
* **title** (str) -- title of the figure.
- * **stylesheet** (list[dict]) -- specifies the style for a group of elements, a class of elements, or a single element \
- (accepts two keys 'selector' and 'style').
+ * **stylesheet** (list[dict]) -- specifies the style for a group of elements, \
+ a class of elements, or a single element (accepts two keys 'selector' and 'style').
* **layout** (dict) -- specifies how the nodes should be positioned on the screen.
:return: network figure within
.
"""
- height = '700px'
- width = '100%'
- if 'height' in args:
- height = args['height']
- if 'width' in args:
- width = args['width']
- cytonet = cyto.Cytoscape(id=identifier,
- stylesheet=args['stylesheet'],
- elements=net,
- layout=args['layout'],
- minZoom = 0.2,
- maxZoom = 1.5,
- #mouseoverNodeData=args['mouseover_node'],
- style={'width': width, 'height': height}
- )
- net_div = html.Div([html.H2(args['title']), cytonet])
-
+ height = "700px"
+ width = "100%"
+ if "height" in args:
+ height = args["height"]
+ if "width" in args:
+ width = args["width"]
+ cytonet = cyto.Cytoscape(
+ id=identifier,
+ stylesheet=args["stylesheet"],
+ elements=net,
+ layout=args["layout"],
+ minZoom=0.2,
+ maxZoom=1.5,
+ # mouseoverNodeData=args['mouseover_node'],
+ style={"width": width, "height": height},
+ )
+ net_div = html.Div([html.H2(args["title"]), cytonet])
return net_div
-def save_DASH_plot(plot, name, plot_format='svg', directory='.', width=800, height=700):
+
+def save_DASH_plot(plot, name, plot_format="svg", directory=".", width=800, height=700):
"""
This function saves a plotly figure to a specified directory, in a determined format.
@@ -2265,68 +3176,67 @@ def save_DASH_plot(plot, name, plot_format='svg', directory='.', width=800, heig
Example::
- result = save_DASH_plot(plot, name='Plot example', plot_format='svg', directory='/data/plots')
+ result = save_DASH_plot(plot, name='Plot example',
+ plot_format='svg', directory='/data/plots')
"""
try:
if not os.path.exists(directory):
os.mkdir(directory)
- plot_file = os.path.join(directory, str(name)+'.'+str(plot_format))
- if plot_format in ['svg', 'pdf', 'png', 'jpeg', 'jpg']:
- if hasattr(plot, 'figure'):
+ plot_file = os.path.join(directory, str(name) + "." + str(plot_format))
+ if plot_format in ["svg", "pdf", "png", "jpeg", "jpg"]:
+ if hasattr(plot, "figure"):
pio.write_image(plot.figure, plot_file, width=width, height=height)
else:
pio.write_image(plot, plot_file, width=width, height=height)
- elif plot_format == 'json':
+ elif plot_format == "json":
figure_json = json.dumps(plot.figure, cls=plotly.utils.PlotlyJSONEncoder)
- with open(plot_file, 'w') as f:
+ with open(plot_file, "w") as f:
f.write(figure_json)
except ValueError as err:
print("Plot could not be saved. Error: {}".format(err))
def mpl_to_plotly(fig, ci=True, legend=True):
- ##ToDo Test how it works for multiple groups
- ##ToDo Allow visualization of CI
+ # ToDo Test how it works for multiple groups
+ # ToDo Allow visualization of CI
# Convert mpl fig obj to plotly fig obj, resize to plotly's default
py_fig = tls.mpl_to_plotly(fig, resize=True)
# Add fill property to lower limit line
- if ci == True:
- style1 = dict(fill='tonexty')
+ if ci:
+ style1 = dict(fill="tonexty")
# apply style
- py_fig['data'][2].update(style1)
+ py_fig["data"][2].update(style1)
# change the default line type to 'step'
- #py_fig.update_traces(dict(line=go.layout.shape.Line({'dash':'solid'})))
- py_fig['data'] = py_fig['data'][0:2]
+ # py_fig.update_traces(dict(line=go.layout.shape.Line({'dash':'solid'})))
+ py_fig["data"] = py_fig["data"][0:2]
# Delete misplaced legend annotations
- py_fig['layout'].pop('annotations', None)
+ py_fig["layout"].pop("annotations", None)
if legend:
# Add legend, place it at the top right corner of the plot
- py_fig['layout'].update(
+ py_fig["layout"].update(
font=dict(size=14),
showlegend=True,
height=400,
width=1000,
- template='plotly_white',
- legend=go.layout.Legend(
- x=1.05,
- y=1
- )
+ template="plotly_white",
+ legend=go.layout.Legend(x=1.05, y=1),
)
# Send updated figure object to Plotly, show result in notebook
return py_fig
+
def get_km_plot_old(data, identifier, args):
figure = {}
if len(data) == 3:
kmfit, summary, plot = data
if kmfit is not None:
- title = 'Kaplan-meier plot' + summary
- if 'title' in args:
- title = args['title'] + "--" + summary
+ title = "Kaplan-meier plot" + summary
+ if "title" in args:
+ title = args["title"] + "--" + summary
plot.set_title(title)
- #p = kmfit.plot(ci_force_lines=True, title=title, show_censors=True)
+ # p = kmfit.plot(ci_force_lines=True, title=title, show_censors=True)
figure = mpl_to_plotly(plot.figure, legend=True)
return dcc.Graph(id=identifier, figure=figure)
@@ -2335,12 +3245,12 @@ def get_km_plot_old(data, identifier, args):
def get_km_plot(data, identifier, args):
figure = {}
plot = plt.subplot(111)
- environment = 'app'
+ environment = "app"
colors = None
- if 'environment' in args:
- environment = args['environment']
- if 'colors' in args:
- colors = args['colors']
+ if "environment" in args:
+ environment = args["environment"]
+ if "colors" in args:
+ colors = args["colors"]
if len(data) == 2:
kmfit, summary = data
if kmfit is not None:
@@ -2351,35 +3261,36 @@ def get_km_plot(data, identifier, args):
c = colors[i]
plot = kmf.plot_survival_function(show_censors=True, ax=plot, c=c)
i += 1
- title = 'Kaplan-meier plot ' + summary
- xlabel = 'Time'
- ylabel = 'Survival'
- if 'title' in args:
- title = args['title'] + "--" + summary
- if 'xlabel' in args:
- xlabel = args['xlabel']
- if 'ylabel' in args:
- ylabel = args['ylabel']
+ title = "Kaplan-meier plot " + summary
+ xlabel = "Time"
+ ylabel = "Survival"
+ if "title" in args:
+ title = args["title"] + "--" + summary
+ if "xlabel" in args:
+ xlabel = args["xlabel"]
+ if "ylabel" in args:
+ ylabel = args["ylabel"]
plot.set_title(title)
plot.set_xlabel(xlabel)
plot.set_ylabel(ylabel)
- if environment == 'app':
- figure = utils.mpl_to_html_image(plot.figure, width=800)
+ if environment == "app":
+ figure = mpl_to_html_image(plot.figure, width=800)
result = html.Div(id=identifier, children=[figure])
else:
result = plot.figure
-
+
return result
+
def get_cumulative_hazard_plot(data, identifier, args):
figure = {}
plot = plt.subplot(111)
- environment = 'app'
+ environment = "app"
colors = None
- if 'environment' in args:
- environment = args['environment']
- if 'colors' in args:
- colors = args['colors']
+ if "environment" in args:
+ environment = args["environment"]
+ if "colors" in args:
+ colors = args["colors"]
if len(data) == 2:
hrfit = data
if hrfit is not None:
@@ -2390,24 +3301,24 @@ def get_cumulative_hazard_plot(data, identifier, args):
c = colors[i]
plot = hrdf.plot_cumulative_hazard(ax=plot, c=c)
i += 1
- title = 'Cumulative Hazard plot '
- xlabel = 'Time'
- ylabel = 'Nelson Aalen - Cumulative Hazard'
- if 'title' in args:
- title = args['title'] + "--"
- if 'xlabel' in args:
- xlabel = args['xlabel']
- if 'ylabel' in args:
- ylabel = args['ylabel']
+ title = "Cumulative Hazard plot "
+ xlabel = "Time"
+ ylabel = "Nelson Aalen - Cumulative Hazard"
+ if "title" in args:
+ title = args["title"] + "--"
+ if "xlabel" in args:
+ xlabel = args["xlabel"]
+ if "ylabel" in args:
+ ylabel = args["ylabel"]
plot.set_title(title)
plot.set_xlabel(xlabel)
plot.set_ylabel(ylabel)
- if environment == 'app':
- figure = utils.mpl_to_html_image(plot.figure, width=800)
+ if environment == "app":
+ figure = mpl_to_html_image(plot.figure, width=800)
result = html.Div(id=identifier, children=[figure])
else:
result = plot.figure
-
+
return result
@@ -2415,113 +3326,155 @@ def get_polar_plot(df, identifier, args):
"""
This function creates a Polar plot with data aggregated for a given group.
- :param dataframe df: dataframe with the data to plot
+ :param pandas.DataFrame df: dataframe with the data to plot
:param str identifier: identifier to be used in the app
- :param dict args: dictionary containing the arguments needed to plot the figure (value_col (value to aggregate), group_col (group by), color_col (color by))
+ :param dict args: dictionary containing the arguments needed to plot the figure (
+ value_col (value to aggregate), group_col (group by), color_col (color by))
:return: Dash Graph
Example::
- figure = get_polar_plot(df, identifier='polar', args={'value_col':'intensity', 'group_col':'modifier', 'color_col':'group'})
+
+ figure = get_polar_plot(df,
+ identifier='polar',
+ args={'value_col':'intensity',
+ 'group_col':'modifier',
+ 'color_col':'group'}
+ )
"""
figure = {}
- line_close = True
- ptype = 'bar'
- title = 'Polar plot'
+ ptype = "bar"
width = 800
height = 700
- value = 'value'
+ value = "value"
group = None
colors = None
if not df.empty:
- if 'value_col' in args:
- value = args['value_col']
- if 'theta_col' in args:
- group = args['theta_col']
- if 'color_col' in args:
- colors = args['color_col']
- if 'line_close' in args:
- line_close = args['line_close']
- if 'title' in args:
- title = args['title']
- if 'width' in args:
- width = args['width']
- if 'height' in args:
- height = args['height']
- if 'type' in args:
- ptype = args['type']
+ if "value_col" in args:
+ value = args["value_col"]
+ if "theta_col" in args:
+ group = args["theta_col"]
+ if "color_col" in args:
+ colors = args["color_col"]
+ if "width" in args:
+ width = args["width"]
+ if "height" in args:
+ height = args["height"]
+ if "type" in args:
+ ptype = args["type"]
figure = go.Figure()
if value is not None and group is not None and colors is not None:
if not df.empty:
min_value = df[value].min()
max_value = df[value].max()
- if ptype == 'line':
+ if ptype == "line":
for color in df[colors].unique():
cdf = df[df[colors] == color]
- figure.add_trace(go.Scatterpolar(r = cdf[value],
- theta = cdf[group],
- mode = 'lines',
- name = color,
- fill='toself'))
+ figure.add_trace(
+ go.Scatterpolar(
+ r=cdf[value],
+ theta=cdf[group],
+ mode="lines",
+ name=color,
+ fill="toself",
+ )
+ )
else:
- print("Type {} not available. Try with 'line' or 'bar' types.".format(ptype))
+ print(
+ "Type {} not available. Try with 'line' or 'bar' types.".format(
+ ptype
+ )
+ )
- layout = figure.update_layout(width=width, height=height, polar = dict(radialaxis=dict(range=[min_value, max_value])))
+ figure.update_layout(
+ width=width,
+ height=height,
+ polar=dict(radialaxis=dict(range=[min_value, max_value])),
+ )
return dcc.Graph(id=identifier, figure=figure)
+
def get_enrichment_plots(enrichment_results, identifier, args):
"""
- This function generates a scatter plot with enriched terms (y-axis) and their adjusted pvalues (x-axis)
+ This function generates a scatter plot with enriched terms (y-axis)
+ and their adjusted pvalues (x-axis)
- :param dataframe enrichment_results: dataframe with the enrichment data to plot (see enrichment functions for format)
+ :param pandas.DataFrame enrichment_results: dataframe with the enrichment data to plot
+ (see enrichment functions for format)
:param str identifier: identifier to be used in the app
- :param dict args: dictionary containing the arguments needed to plot the figure (width, height, title)
- :return list: list of scatter plots one for each enrichment table available (i.e pairwise comparisons)
+ :param dict args: dictionary containing the arguments needed to plot the figure
+ (width, height, title)
+ :return list: list of scatter plots one for each enrichment table available
+ (i.e pairwise comparisons)
Example::
- figure = get_enrichment_plots(df, identifier='enrichment', args={'width':1500, 'height':800, 'title':'Enrichment'})
+
+ figure = get_enrichment_plots(df,
+ identifier='enrichment',
+ args={'width':1500,
+ 'height':800,
+ 'title':'Enrichment'}
+ )
"""
figures = []
width = 900
height = 800
- colors = {'upregulated': '#cb181d', 'downregulated': '#3288bd', 'regulated': '#ae017e', 'non-regulated': '#fcc5c0'}
+ colors = {
+ "upregulated": "#cb181d",
+ "downregulated": "#3288bd",
+ "regulated": "#ae017e",
+ "non-regulated": "#fcc5c0",
+ }
title = "Enrichment"
- if 'width' in args:
- width = args['width']
- if 'height' in args:
- height = args['height']
- if 'title' in args:
- title = args['title']
+ if "width" in args:
+ width = args["width"]
+ if "height" in args:
+ height = args["height"]
+ if "title" in args:
+ title = args["title"]
if not isinstance(enrichment_results, dict):
aux = enrichment_results.copy()
- enrichment_results = {'regulated~non-regulated': aux}
+ enrichment_results = {"regulated~non-regulated": aux}
for g in enrichment_results:
- g1, g2 = g.split('~')
- group = 'direction'
- nid = identifier+'_{}_{}'.format(g1, g2)
+ g1, g2 = g.split("~")
+ group = "direction"
+ nid = identifier + "_{}_{}".format(g1, g2)
if not enrichment_results[g].empty:
df = enrichment_results[g][enrichment_results[g].rejected]
- if 'direction' not in df:
+ if "direction" not in df:
group = None
if not df.empty:
- df = df.sort_values(by=[group, 'padj'], ascending=False)
- df['x'] = -np.log10(df['padj'])
- fig = get_scatterplot(df, identifier=nid,
- args={'x': 'x',
- 'y': 'terms',
- 'group': group,
- 'title':'{} {} vs {}'.format(title, g1, g2),
- 'symbol':group,
- 'colors': colors,
- 'x_title':'-log10(padj)',
- 'y_title':'Enriched terms',
- 'width': width,
- 'height':height,
- 'hovering_cols':['foreground', 'foreground_pop', 'background', 'background_pop', 'pvalue', 'padj', 'identifiers'],
- 'size':'foreground'})
+ df = df.sort_values(by=[group, "padj"], ascending=False)
+ df["x"] = -np.log10(df["padj"])
+ fig = get_scatterplot(
+ df,
+ identifier=nid,
+ args={
+ "x": "x",
+ "y": "terms",
+ "group": group,
+ "title": "{} {} vs {}".format(title, g1, g2),
+ "symbol": group,
+ "colors": colors,
+ "x_title": "-log10(padj)",
+ "y_title": "Enriched terms",
+ "width": width,
+ "height": height,
+ "hovering_cols": [
+ "foreground",
+ "foreground_pop",
+ "background",
+ "background_pop",
+ "pvalue",
+ "padj",
+ "identifiers",
+ ],
+ "size": "foreground",
+ },
+ )
figures.append(fig)
return figures
diff --git a/src/vuecore/wgcna.py b/src/vuecore/wgcna.py
new file mode 100644
index 0000000..92c29ec
--- /dev/null
+++ b/src/vuecore/wgcna.py
@@ -0,0 +1,795 @@
+import numpy as np
+import pandas as pd
+import plotly.graph_objs as go
+import plotly.subplots as tools
+import scipy as scp
+from acore import wgcna_analysis
+
+from . import color_list, dendrogram
+
+
+def get_module_color_annotation(
+ map_list,
+ col_annotation=False,
+ row_annotation=False,
+ bygene=False,
+ module_colors=[],
+ dendrogram=[],
+):
+ """
+ This function takes a list of values, converts them into colors, and creates a new plotly object to be used as an annotation.
+ Options module_colors and dendrogram only apply when map_list is a list of experimental features used in module eigenegenes calculation.
+
+ :param list map_list: dendrogram leaf labels.
+ :param bool col_annotation: if True, adds color annotations as a row.
+ :param bool row_annotation: if True, adds color annotations as a column.
+ :param bool bygene: determines wether annotation colors have to be reordered to match dendrogram leaf labels.
+ :param list module_colors: dendrogram leaf module color.
+ :param dict dendrogram: dendrogram represented as a plotly object figure.
+ :return: Plotly object figure.
+
+ .. note:: map_list and module_colors must have the same length.
+ """
+ colors_dict = color_list.make_color_dict()
+
+ n = len(map_list)
+ val = 1 / (n - 1)
+ number = 0
+ colors = []
+ vals = []
+
+ # Use if color annotation is for experimental features in dendrogram
+ if bygene:
+ module_colors = [i.lower().replace(" ", "") for i in module_colors]
+ gene_colors = dict(zip(map_list, module_colors))
+
+ for i in map_list:
+ name = gene_colors[i]
+ color = colors_dict[name]
+ n = number
+ colors.append([round(n, 4), color])
+ vals.append((i, round(n, 4)))
+ number = n + val
+
+ labels = list(dendrogram["layout"]["xaxis"]["ticktext"])
+ y = [1] * len(labels)
+
+ df = pd.DataFrame([labels, y], index=["labels", "y"]).T
+ df["vals"] = df["labels"].map(dict(vals))
+
+ # Use if map_list is a list of co-expression modules names
+ else:
+ for i in map_list:
+ name = i.split("ME")
+ if len(name) == 2:
+ name = name[1]
+ color = colors_dict[name]
+ n = number
+ colors.append([round(n, 4), color])
+ vals.append((i, round(n, 4)))
+ number = n + val
+ else:
+ name = name[0]
+ n = number
+ colors.append([round(n, 4), "#ffffff"])
+ vals.append((i, round(n, 4)))
+ number = n + val
+
+ y = [1] * len(map_list)
+ df = pd.DataFrame([map_list, y], index=["labels", "y"]).T
+ df["vals"] = df["labels"].map(dict(vals))
+
+ if row_annotation and col_annotation:
+ r_annot = go.Heatmap(
+ z=df.vals,
+ x=df.y,
+ y=df.labels,
+ showscale=False,
+ colorscale=colors,
+ xaxis="x",
+ yaxis="y",
+ )
+ c_annot = go.Heatmap(
+ z=df.vals,
+ x=df.labels,
+ y=df.y,
+ showscale=False,
+ colorscale=colors,
+ xaxis="x2",
+ yaxis="y2",
+ )
+ return r_annot, c_annot
+ elif row_annotation:
+ r_annot = go.Heatmap(
+ z=df.vals,
+ x=df.y,
+ y=df.labels,
+ showscale=False,
+ colorscale=colors,
+ xaxis="x2",
+ yaxis="y2",
+ )
+ return r_annot
+ elif col_annotation:
+ c_annot = go.Heatmap(
+ z=df.vals,
+ x=df.labels,
+ y=df.y,
+ showscale=False,
+ colorscale=colors,
+ xaxis="x2",
+ yaxis="y2",
+ )
+ return c_annot
+
+ return None
+
+
+def get_heatmap(df, colorscale=None, color_missing=True):
+ """
+ This function plots a simple Plotly heatmap.
+
+ :param df: pandas dataframe containing experimental data, with samples/subjects as rows and features as columns.
+ :param list[list] colorscale: heatmap colorscale (e.g. [[0,'#67a9cf'],[0.5,'#f7f7f7'],[1,'#ef8a62']]). If colorscale is not defined, will take [[0, 'rgb(255,255,255)'], [1, 'rgb(255,51,0)']] as default.
+ :param bool color_missing: if set to True, plots missing values as grey in the heatmap.
+ :return: Plotly object figure.
+ """
+ figure = {}
+ if df is not None:
+ if colorscale:
+ colors = colorscale
+ else:
+ colors = [[0, "rgb(255,255,255)"], [1, "rgb(255,51,0)"]]
+
+ figure = {"layout": {"template": None}, "data": []}
+ figure["layout"]["template"] = "plotly_white"
+ figure["data"].append(
+ go.Heatmap(
+ z=df.values.tolist(),
+ y=list(df.index),
+ x=list(df.columns),
+ colorscale=colors,
+ showscale=True,
+ colorbar=dict(
+ x=1, y=0, xanchor="left", yanchor="bottom", len=0.35, thickness=15
+ ),
+ )
+ )
+ if color_missing:
+ df_missing = wgcna_analysis.get_miss_values_df(df)
+ figure["data"].append(
+ go.Heatmap(
+ z=df_missing.values.tolist(),
+ y=list(df.index),
+ x=list(df.columns),
+ colorscale=[[0, "rgb(201,201,201)"], [1, "rgb(201,201,201)"]],
+ showscale=False,
+ )
+ )
+
+ return figure
+
+
+def plot_labeled_heatmap(
+ df,
+ textmatrix,
+ title,
+ colorscale=[[0, "rgb(0,255,0)"], [0.5, "rgb(255,255,255)"], [1, "rgb(255,0,0)"]],
+ width=1200,
+ height=800,
+ row_annotation=False,
+ col_annotation=False,
+):
+ """
+ This function plots a simple Plotly heatmap with column and/or row annotations and heatmap annotations.
+
+ :param df: pandas dataframe containing data to be plotted in the heatmap.
+ :param textmatrix: pandas dataframe with heatmap annotations as values.
+ :param str title: the title of the figure.
+ :param list[list] colorscale: heatmap colorscale (e.g. [[0,'rgb(0,255,0)'],[0.5,'rgb(255,255,255)'],[1,'rgb(255,0,0)']])
+ :param int width: the width of the figure.
+ :param int height: the height of the figure.
+ :param bool row_annotation: if True, adds a color-coded column at the left of the heatmap.
+ :param bool col_annotation: if True, adds a color-coded row at the bottom of the heatmap.
+ :return: Plotly object figure.
+ """
+ figure = {}
+ if df is not None:
+ figure = get_heatmap(df, colorscale=colorscale, color_missing=False)
+ figure["data"].append(
+ get_module_color_annotation(
+ list(df.index),
+ row_annotation=row_annotation,
+ col_annotation=col_annotation,
+ bygene=False,
+ )
+ )
+
+ annotations = []
+ for n, row in enumerate(textmatrix.values):
+ for m, val in enumerate(row):
+ annotations.append(
+ go.layout.Annotation(
+ text=str(textmatrix.values[n][m]),
+ font=dict(size=8),
+ x=df.columns[m],
+ y=df.index[n],
+ xref="x",
+ yref="y",
+ showarrow=False,
+ )
+ )
+
+ layout = go.Layout(
+ width=width,
+ height=height,
+ title=title,
+ xaxis=dict(
+ domain=[0.015, 1],
+ autorange=True,
+ showgrid=False,
+ zeroline=False,
+ showline=False,
+ ticks="",
+ showticklabels=True,
+ automargin=True,
+ anchor="y",
+ ),
+ yaxis=dict(
+ autorange="reversed",
+ ticklen=5,
+ ticks="outside",
+ tickcolor="white",
+ showticklabels=False,
+ automargin=True,
+ showgrid=False,
+ anchor="x",
+ ),
+ xaxis2=dict(
+ domain=[0, 0.01],
+ autorange=True,
+ showgrid=False,
+ zeroline=False,
+ showline=False,
+ ticks="",
+ showticklabels=False,
+ automargin=True,
+ anchor="y2",
+ ),
+ yaxis2=dict(
+ autorange="reversed",
+ showgrid=False,
+ zeroline=False,
+ showline=False,
+ ticks="",
+ showticklabels=True,
+ automargin=True,
+ anchor="x2",
+ ),
+ )
+
+ figure["layout"] = layout
+ figure["layout"]["template"] = "plotly_white"
+ figure["layout"].update(annotations=annotations)
+
+ return figure
+
+
+def plot_dendrogram_guidelines(Z_tree, dendrogram):
+ """
+ This function takes a dendrogram tree dictionary and its plotly object and creates shapes to be plotted as vertical dashed lines in the dendrogram.
+
+ :param dict Z_tree: dictionary of data structures computed to render the dendrogram. Keys: 'icoords', 'dcoords', 'ivl' and 'leaves'.
+ :param dendrogram: dendrogram represented as a plotly object figure.
+ :return: List of dictionaries.
+ """
+ shapes = []
+ if dendrogram is not None:
+ tickvals = list(dendrogram["layout"]["xaxis"]["tickvals"])
+ maximum = len(tickvals)
+ step = int(maximum / 8)
+ minimum = int(0 + step)
+
+ keys = ["type", "x0", "y0", "x1", "y1", "line"]
+ line_keys = ["color", "width", "dash"]
+ line_vals = ["rgb(192,192,192)", 0.1, "dot"]
+ line = dict(zip(line_keys, line_vals))
+
+ values = []
+ for i in tickvals[minimum::step]:
+ values.append(("line", i, 0.3, i, np.max(Z_tree["dcoord"])))
+
+ values = [list(i) + [line] for i in values]
+ shapes = []
+ for i in values:
+ d = dict(zip(keys, i))
+ shapes.append(d)
+
+ return shapes
+
+
+def plot_intramodular_correlation(
+ MM, FS, feature_module_df, title, width=1000, height=800
+):
+ """
+ This function uses the Feature significance and Module Membership measures, and plots a multi-scatter plot of all modules against all clinical traits.
+
+ :param MM: pandas dataframe with module membership data
+ :param FS: pandas dataframe with feature significance data
+ :param feature_module_df: pandas DataFrame of experimental features and module colors (use mode='dataframe' in get_FeaturesPerModule)
+ :param str title: plot title
+ :param int width: plot width
+ :param int height: plot height
+ :return: Plotly object figure.
+
+ Example::
+
+ plot = plot_intramodular_correlation(MM, FS, feature_module_df, title='Plot', width=1000, height=800):
+
+ .. note:: There is a limit in the number of subplots one can make in Plotly. This function limits the number of modules shown to 5.
+ """
+ figure = {}
+ if MM is not None:
+ MM = MM.iloc[:, -6]
+ MM["modColor"] = MM.index.map(
+ feature_module_df.set_index("name")["modColor"].get
+ )
+
+ figure = tools.make_subplots(
+ rows=len(FS.columns),
+ cols=len(MM.columns) - 1,
+ shared_xaxes=False,
+ shared_yaxes=False,
+ vertical_spacing=0.015,
+ horizontal_spacing=0.1,
+ print_grid=True,
+ )
+
+ figure.layout.template = "plotly_white"
+ layout = dict(width=width, height=height, showlegend=False, title=title)
+ figure.layout.update(layout)
+
+ axis_dict = {}
+ for i, j in enumerate(MM.columns[MM.columns.str.startswith("MM")]):
+ n_p = len(FS.columns) * (len(MM.columns) - 1) - len(
+ MM.columns[MM.columns.str.startswith("MM")]
+ )
+ axis_dict["xaxis{}".format(n_p + i + 1)] = dict(
+ title=j, titlefont=dict(size=13)
+ )
+ print(axis_dict)
+ n = 1
+ for a, b in enumerate(FS.columns):
+ name = b.split(" ")
+ if len(name) > 1:
+ label = ["
".join(name[i : i + 3]) for i in range(0, len(name), 3)][
+ 0
+ ]
+ else:
+ label = name[0]
+ axis_dict["yaxis{}".format(a + n)] = dict(
+ title=label, titlefont=dict(size=13)
+ )
+ n += len(MM.columns[MM.columns.str.startswith("MM")]) - 1
+
+ annotation = []
+ x_axis = 1
+ y_axis = 1
+ for a, b in enumerate(FS.columns):
+ for i, j in enumerate(MM.columns[MM.columns.str.startswith("MM")]):
+ name = MM[MM["modColor"] == j[2:]].index
+ x = abs(MM[MM["modColor"] == j[2:]][j].values)
+ y = abs(FS[FS.index.isin(name)][b].values)
+
+ slope, intercept, r_value, p_value, std_err = scp.stats.linregress(x, y)
+ line = slope * x + intercept
+
+ figure.append_trace(
+ go.Scattergl(
+ x=x,
+ y=y,
+ text=name,
+ mode="markers",
+ opacity=0.7,
+ marker={
+ "size": 7,
+ "color": "white",
+ "line": {"width": 1.5, "color": j[2:]},
+ },
+ ),
+ a + 1,
+ i + 1,
+ )
+
+ figure.append_trace(
+ go.Scattergl(x=x, y=line, mode="lines", marker={"color": "black"}),
+ a + 1,
+ i + 1,
+ )
+
+ annot = dict(
+ x=0.7,
+ y=0.7,
+ xref="x{}".format(x_axis),
+ yref="y{}".format(y_axis),
+ text="R={:0.2}, p={:.0e}".format(r_value, p_value),
+ showarrow=False,
+ )
+ annotation.append(annot)
+ x_axis += 1
+ y_axis += 1
+
+ figure.layout.update(axis_dict)
+ figure.layout.update(annotations=annotation)
+
+ return figure
+
+
+def plot_complex_dendrogram(
+ dendro_df,
+ subplot_df,
+ title,
+ dendro_labels=[],
+ distfun="euclidean",
+ linkagefun="average",
+ hang=0.04,
+ subplot="module colors",
+ subplot_colorscale=[],
+ color_missingvals=True,
+ row_annotation=False,
+ col_annotation=False,
+ width=1000,
+ height=800,
+):
+ """
+ This function plots a dendrogram with a subplot below that can be a heatmap (annotated or not) or module colors.
+
+ :param dendro_df: pandas dataframe containing data used to generate dendrogram, columns will result in dendrogram leaves.
+ :param subplot_df: pandas dataframe containing data used to generate plot below dendrogram.
+ :param str title: the title of the figure.
+ :param list dendro_labels: list of strings for dendrogram leaf nodes labels.
+ :param str distfun: distance measure to be used (‘euclidean‘, ‘maximum‘, ‘manhattan‘, ‘canberra‘, ‘binary‘, ‘minkowski‘ or ‘jaccard‘).
+ :param str linkagefun: hierarchical/agglomeration method to be used (‘single‘, ‘complete‘, ‘average‘, ‘weighted‘, ‘centroid‘, ‘median‘ or ‘ward‘).
+ :param float hang: height at which the dendrogram leaves should be placed.
+ :param str subplot: type of plot to be shown below the dendrogram (´module colors´ or ´heatmap´).
+ :param list subplot_colorscale: colorscale to be used in the subplot.
+ :param bool color_missingvals: if set to `True`, plots missing values as grey in the heatmap.
+ :param bool row_annotation: if `True`, adds a color-coded column at the left of the heatmap.
+ :param bool col_annotation: if `True`, adds a color-coded row at the bottom of the heatmap.
+ :param int width: the width of the figure.
+ :param int height: the height of the figure.
+ :return: Plotly object figure.
+ """
+ figure = {}
+ dendro_tree = wgcna_analysis.get_dendrogram(
+ dendro_df,
+ dendro_labels,
+ distfun=distfun,
+ linkagefun=linkagefun,
+ div_clusters=False,
+ )
+ if dendro_tree is not None:
+ dendrogram_ = dendrogram.plot_dendrogram(
+ dendro_tree, hang=hang, cutoff_line=False
+ )
+
+ layout = go.Layout(
+ width=width,
+ height=height,
+ showlegend=False,
+ title=title,
+ xaxis=dict(
+ domain=[0, 1],
+ range=[
+ np.min(dendrogram_["layout"]["xaxis"]["tickvals"]) - 6,
+ np.max(dendrogram_["layout"]["xaxis"]["tickvals"]) + 4,
+ ],
+ showgrid=False,
+ zeroline=True,
+ ticks="",
+ automargin=True,
+ anchor="y",
+ ),
+ yaxis=dict(
+ domain=[0.7, 1],
+ autorange=True,
+ showgrid=False,
+ zeroline=False,
+ ticks="outside",
+ title="Height",
+ automargin=True,
+ anchor="x",
+ ),
+ xaxis2=dict(
+ domain=[0, 1],
+ autorange=True,
+ showgrid=True,
+ zeroline=False,
+ ticks="",
+ showticklabels=False,
+ automargin=True,
+ anchor="y2",
+ ),
+ yaxis2=dict(
+ domain=[0, 0.64],
+ autorange=True,
+ showgrid=False,
+ zeroline=False,
+ automargin=True,
+ anchor="x2",
+ ),
+ )
+
+ if subplot == "module colors":
+ figure = tools.make_subplots(rows=2, cols=1, print_grid=False)
+
+ for i in list(dendrogram_["data"]):
+ figure.append_trace(i, 1, 1)
+
+ shapes = plot_dendrogram_guidelines(dendro_tree, dendrogram_)
+ moduleColors = get_module_color_annotation(
+ dendro_labels,
+ col_annotation=col_annotation,
+ bygene=True,
+ module_colors=subplot_df,
+ dendrogram=dendrogram_,
+ )
+ figure.append_trace(moduleColors, 2, 1)
+ figure["layout"] = layout
+ figure.layout.template = "plotly_white"
+ figure["layout"].update(
+ {
+ "shapes": shapes,
+ "xaxis": dict(showticklabels=False),
+ "yaxis": dict(domain=[0.2, 1]),
+ "yaxis2": dict(
+ domain=[0, 0.19],
+ title="Module colors",
+ ticks="",
+ showticklabels=False,
+ ),
+ }
+ )
+
+ elif subplot == "heatmap":
+ if not all(
+ list(
+ subplot_df.columns.map(
+ lambda x: subplot_df[x].between(-1, 1, inclusive=True).all()
+ )
+ )
+ ):
+ df = wgcna_analysis.get_percentiles_heatmap(
+ subplot_df, dendro_tree, bydendro=True, bycols=False
+ ).T
+ else:
+ df = wgcna_analysis.df_sort_by_dendrogram(
+ wgcna_analysis.df_sort_by_dendrogram(subplot_df, dendro_tree).T,
+ dendro_tree,
+ )
+
+ heatmap = get_heatmap(
+ df, colorscale=subplot_colorscale, color_missing=color_missingvals
+ )
+
+ if row_annotation and col_annotation:
+ figure = tools.make_subplots(
+ rows=3,
+ cols=2,
+ specs=[[{"colspan": 2}, None], [{}, {}], [{"colspan": 2}, None]],
+ print_grid=False,
+ )
+ for i in list(dendrogram_["data"]):
+ figure.append_trace(i, 1, 1)
+ for j in list(heatmap["data"]):
+ figure.append_trace(j, 2, 2)
+
+ r_annot, c_annot = get_module_color_annotation(
+ list(df.index),
+ row_annotation=row_annotation,
+ col_annotation=col_annotation,
+ bygene=False,
+ )
+ figure.append_trace(r_annot, 2, 1)
+ figure.append_trace(c_annot, 3, 1)
+
+ figure["layout"] = layout
+ figure.layout.template = "plotly_white"
+ figure["layout"].update(
+ {
+ "xaxis": dict(ticks="", showticklabels=False, anchor="y"),
+ "xaxis2": dict(
+ domain=[0, 0.01],
+ ticks="",
+ showticklabels=False,
+ automargin=True,
+ anchor="y2",
+ ),
+ "xaxis3": dict(
+ domain=[0.015, 1],
+ ticks="",
+ showticklabels=False,
+ automargin=True,
+ anchor="y3",
+ ),
+ "xaxis4": dict(
+ domain=[0.015, 1],
+ ticks="",
+ showticklabels=True,
+ automargin=True,
+ anchor="y4",
+ ),
+ "yaxis": dict(domain=[0.635, 1], automargin=True, anchor="x"),
+ "yaxis2": dict(
+ domain=[0.015, 0.635],
+ autorange="reversed",
+ ticks="",
+ showticklabels=True,
+ automargin=True,
+ anchor="x2",
+ ),
+ "yaxis3": dict(
+ domain=[0.01, 0.635],
+ autorange="reversed",
+ ticks="",
+ showticklabels=False,
+ automargin=True,
+ anchor="x3",
+ ),
+ "yaxis4": dict(
+ domain=[0, 0.01],
+ ticks="",
+ showticklabels=False,
+ automargin=True,
+ anchor="x4",
+ ),
+ }
+ )
+
+ elif not row_annotation and not col_annotation:
+ figure = tools.make_subplots(rows=2, cols=1, print_grid=False)
+
+ for i in list(dendrogram_["data"]):
+ figure.append_trace(i, 1, 1)
+ for j in list(heatmap["data"]):
+ figure.append_trace(j, 2, 1)
+
+ figure["layout"] = layout
+ figure.layout.template = "plotly_white"
+ figure.layout.update(
+ {
+ "xaxis": dict(
+ ticktext=np.array(
+ dendrogram_["layout"]["xaxis"]["ticktext"]
+ ),
+ tickvals=list(dendrogram_["layout"]["xaxis"]["tickvals"]),
+ ),
+ "yaxis2": dict(autorange="reversed"),
+ }
+ )
+
+ elif row_annotation:
+ figure = tools.make_subplots(
+ rows=2,
+ cols=2,
+ specs=[[{"colspan": 2}, None], [{}, {}]],
+ print_grid=False,
+ )
+ for i in list(dendrogram_["data"]):
+ figure.append_trace(i, 1, 1)
+ for j in list(heatmap["data"]):
+ figure.append_trace(j, 2, 2)
+
+ r_annot = get_module_color_annotation(
+ list(df.index),
+ row_annotation=row_annotation,
+ col_annotation=col_annotation,
+ bygene=False,
+ )
+ figure.append_trace(r_annot, 2, 1)
+
+ figure["layout"] = layout
+ figure.layout.template = "plotly_white"
+ figure["layout"].update(
+ {
+ "xaxis": dict(
+ domain=[0.015, 1],
+ ticktext=np.array(
+ dendrogram_["layout"]["xaxis"]["ticktext"]
+ ),
+ tickvals=list(dendrogram_["layout"]["xaxis"]["tickvals"]),
+ automargin=True,
+ anchor="y",
+ ),
+ "xaxis2": dict(
+ domain=[0, 0.010],
+ ticks="",
+ showticklabels=False,
+ automargin=True,
+ anchor="y2",
+ ),
+ "xaxis3": dict(
+ domain=[0.015, 1],
+ ticks="",
+ showticklabels=False,
+ automargin=True,
+ anchor="y3",
+ ),
+ "yaxis": dict(automargin=True, anchor="x"),
+ "yaxis2": dict(
+ autorange="reversed",
+ ticks="",
+ showticklabels=True,
+ automargin=True,
+ anchor="x2",
+ ),
+ "yaxis3": dict(
+ domain=[0, 0.64],
+ ticks="",
+ showticklabels=False,
+ automargin=True,
+ anchor="x3",
+ ),
+ }
+ )
+
+ elif col_annotation:
+ figure = tools.make_subplots(
+ rows=3, cols=1, specs=[[{}], [{}], [{}]], print_grid=False
+ )
+
+ for i in list(dendrogram_["data"]):
+ figure.append_trace(i, 1, 1)
+ for j in list(heatmap["data"]):
+ figure.append_trace(j, 3, 1)
+
+ c_annot = get_module_color_annotation(
+ list(df.index),
+ row_annotation=row_annotation,
+ col_annotation=col_annotation,
+ bygene=False,
+ )
+ figure.append_trace(c_annot, 2, 1)
+
+ figure["layout"] = layout
+ figure.layout.template = "plotly_white"
+ figure["layout"].update(
+ {
+ "xaxis": dict(
+ ticktext=np.array(
+ dendrogram_["layout"]["xaxis"]["ticktext"]
+ ),
+ tickvals=list(dendrogram_["layout"]["xaxis"]["tickvals"]),
+ automargin=True,
+ anchor="y",
+ ),
+ "xaxis2": dict(
+ ticks="", showticklabels=False, automargin=True, anchor="y2"
+ ),
+ "xaxis3": dict(
+ domain=[0, 1],
+ ticks="",
+ showticklabels=False,
+ automargin=True,
+ anchor="y3",
+ ),
+ "yaxis": dict(domain=[0.70, 1], automargin=True, anchor="x"),
+ "yaxis2": dict(
+ domain=[0.615, 0.625],
+ ticks="",
+ showticklabels=False,
+ automargin=True,
+ anchor="x2",
+ ),
+ "yaxis3": dict(
+ domain=[0, 0.61],
+ autorange="reversed",
+ ticks="",
+ showticklabels=False,
+ automargin=True,
+ anchor="x3",
+ ),
+ }
+ )
+
+ return figure
diff --git a/src/vuecore/wgcnaFigures.py b/src/vuecore/wgcnaFigures.py
deleted file mode 100644
index b0d3390..0000000
--- a/src/vuecore/wgcnaFigures.py
+++ /dev/null
@@ -1,412 +0,0 @@
-import pandas as pd
-import numpy as np
-import scipy as scp
-from ckg.analytics_core.viz import color_list
-import plotly.graph_objs as go
-import plotly.subplots as tools
-from ckg.analytics_core.viz import Dendrogram
-from ckg.analytics_core.analytics import wgcnaAnalysis
-
-
-def get_module_color_annotation(map_list, col_annotation=False, row_annotation=False, bygene=False, module_colors=[], dendrogram=[]):
- """
- This function takes a list of values, converts them into colors, and creates a new plotly object to be used as an annotation.
- Options module_colors and dendrogram only apply when map_list is a list of experimental features used in module eigenegenes calculation.
-
- :param list map_list: dendrogram leaf labels.
- :param bool col_annotation: if True, adds color annotations as a row.
- :param bool row_annotation: if True, adds color annotations as a column.
- :param bool bygene: determines wether annotation colors have to be reordered to match dendrogram leaf labels.
- :param list module_colors: dendrogram leaf module color.
- :param dict dendrogram: dendrogram represented as a plotly object figure.
- :return: Plotly object figure.
-
- .. note:: map_list and module_colors must have the same length.
- """
- colors_dict = color_list.make_color_dict()
-
- n = len(map_list)
- val = 1/(n-1)
- number = 0
- colors = []
- vals = []
-
- #Use if color annotation is for experimental features in dendrogram
- if bygene:
- module_colors = [i.lower().replace(' ', '') for i in module_colors]
- gene_colors = dict(zip(map_list, module_colors))
-
- for i in map_list:
- name = gene_colors[i]
- color = colors_dict[name]
- n = number
- colors.append([round(n,4), color])
- vals.append((i, round(n,4)))
- number = n+val
-
- labels = list(dendrogram['layout']['xaxis']['ticktext'])
- y = [1]*len(labels)
-
- df = pd.DataFrame([labels, y], index=['labels', 'y']).T
- df['vals'] = df['labels'].map(dict(vals))
-
- #Use if map_list is a list of co-expression modules names
- else:
- for i in map_list:
- name = i.split('ME')
- if len(name) == 2:
- name = name[1]
- color = colors_dict[name]
- n = number
- colors.append([round(n,4), color])
- vals.append((i, round(n,4)))
- number = n+val
- else:
- name = name[0]
- n = number
- colors.append([round(n,4), '#ffffff'])
- vals.append((i, round(n,4)))
- number = n+val
-
- y = [1]*len(map_list)
- df = pd.DataFrame([map_list, y], index=['labels', 'y']).T
- df['vals'] = df['labels'].map(dict(vals))
-
- if row_annotation and col_annotation:
- r_annot = go.Heatmap(z=df.vals, x=df.y, y=df.labels, showscale=False, colorscale=colors, xaxis='x', yaxis='y')
- c_annot = go.Heatmap(z=df.vals, x=df.labels, y=df.y, showscale=False, colorscale=colors, xaxis='x2', yaxis='y2')
- return r_annot, c_annot
- elif row_annotation:
- r_annot = go.Heatmap(z=df.vals, x=df.y, y=df.labels, showscale=False, colorscale=colors, xaxis='x2', yaxis='y2')
- return r_annot
- elif col_annotation:
- c_annot = go.Heatmap(z=df.vals, x=df.labels, y=df.y, showscale=False, colorscale=colors, xaxis='x2', yaxis='y2')
- return c_annot
-
- return None
-
-
-def get_heatmap(df, colorscale=None, color_missing=True):
- """
- This function plots a simple Plotly heatmap.
-
- :param df: pandas dataframe containing experimental data, with samples/subjects as rows and features as columns.
- :param list[list] colorscale: heatmap colorscale (e.g. [[0,'#67a9cf'],[0.5,'#f7f7f7'],[1,'#ef8a62']]). If colorscale is not defined, will take [[0, 'rgb(255,255,255)'], [1, 'rgb(255,51,0)']] as default.
- :param bool color_missing: if set to True, plots missing values as grey in the heatmap.
- :return: Plotly object figure.
- """
- figure = {}
- if df is not None:
- if colorscale:
- colors = colorscale
- else:
- colors = [[0, 'rgb(255,255,255)'], [1, 'rgb(255,51,0)']]
-
- figure = {'layout': {'template': None}, 'data': []}
- figure['layout']['template'] = 'plotly_white'
- figure['data'].append(go.Heatmap(z=df.values.tolist(), y=list(df.index), x=list(df.columns),
- colorscale=colors, showscale=True,
- colorbar=dict(x=1, y=0, xanchor='left', yanchor='bottom', len=0.35, thickness=15)))
- if color_missing:
- df_missing = wgcnaAnalysis.get_miss_values_df(df)
- figure['data'].append(go.Heatmap(z=df_missing.values.tolist(),
- y=list(df.index),
- x=list(df.columns),
- colorscale=[[0, 'rgb(201,201,201)'], [1, 'rgb(201,201,201)']],
- showscale=False))
-
- return figure
-
-
-def plot_labeled_heatmap(df, textmatrix, title, colorscale=[[0, 'rgb(0,255,0)'], [0.5, 'rgb(255,255,255)'], [1, 'rgb(255,0,0)']], width=1200, height=800, row_annotation=False, col_annotation=False):
- """
- This function plots a simple Plotly heatmap with column and/or row annotations and heatmap annotations.
-
- :param df: pandas dataframe containing data to be plotted in the heatmap.
- :param textmatrix: pandas dataframe with heatmap annotations as values.
- :param str title: the title of the figure.
- :param list[list] colorscale: heatmap colorscale (e.g. [[0,'rgb(0,255,0)'],[0.5,'rgb(255,255,255)'],[1,'rgb(255,0,0)']])
- :param int width: the width of the figure.
- :param int height: the height of the figure.
- :param bool row_annotation: if True, adds a color-coded column at the left of the heatmap.
- :param bool col_annotation: if True, adds a color-coded row at the bottom of the heatmap.
- :return: Plotly object figure.
- """
- figure = {}
- if df is not None:
- figure = get_heatmap(df, colorscale=colorscale, color_missing=False)
- figure['data'].append(get_module_color_annotation(list(df.index), row_annotation=row_annotation, col_annotation=col_annotation, bygene=False))
-
- annotations = []
- for n, row in enumerate(textmatrix.values):
- for m, val in enumerate(row):
- annotations.append(go.layout.Annotation(text=str(textmatrix.values[n][m]), font=dict(size=8),
- x=df.columns[m], y=df.index[n], xref='x', yref='y', showarrow=False))
-
- layout = go.Layout(width=width, height=height, title=title,
- xaxis=dict(domain=[0.015, 1], autorange=True, showgrid=False, zeroline=False, showline=False, ticks='', showticklabels=True, automargin=True, anchor='y'),
- yaxis=dict(autorange='reversed', ticklen=5, ticks='outside', tickcolor='white', showticklabels=False, automargin=True, showgrid=False, anchor='x'),
- xaxis2=dict(domain=[0, 0.01], autorange=True, showgrid=False, zeroline=False, showline=False, ticks='', showticklabels=False, automargin=True, anchor='y2'),
- yaxis2=dict(autorange='reversed', showgrid=False, zeroline=False, showline=False, ticks='', showticklabels=True, automargin=True, anchor='x2'))
-
- figure['layout'] = layout
- figure['layout']['template'] = 'plotly_white'
- figure['layout'].update(annotations=annotations)
-
-
- return figure
-
-
-def plot_dendrogram_guidelines(Z_tree, dendrogram):
- """
- This function takes a dendrogram tree dictionary and its plotly object and creates shapes to be plotted as vertical dashed lines in the dendrogram.
-
- :param dict Z_tree: dictionary of data structures computed to render the dendrogram. Keys: 'icoords', 'dcoords', 'ivl' and 'leaves'.
- :param dendrogram: dendrogram represented as a plotly object figure.
- :return: List of dictionaries.
- """
- shapes = []
- if dendrogram is not None:
- tickvals = list(dendrogram['layout']['xaxis']['tickvals'])
- maximum = len(tickvals)
- step = int(maximum/8)
- minimum = int(0+step)
-
- keys = ['type', 'x0', 'y0', 'x1', 'y1', 'line']
- line_keys = ['color', 'width', 'dash']
- line_vals = ['rgb(192,192,192)', 0.1, 'dot']
- line = dict(zip(line_keys,line_vals))
-
- values = []
- for i in tickvals[minimum::step]:
- values.append(('line', i, 0.3, i, np.max(Z_tree['dcoord'])))
-
- values = [list(i)+[line] for i in values]
- shapes = []
- for i in values:
- d = dict(zip(keys, i))
- shapes.append(d)
-
- return shapes
-
-
-def plot_intramodular_correlation(MM, FS, feature_module_df, title, width=1000, height=800):
- """
- This function uses the Feature significance and Module Membership measures, and plots a multi-scatter plot of all modules against all clinical traits.
-
- :param MM: pandas dataframe with module membership data
- :param FS: pandas dataframe with feature significance data
- :param feature_module_df: pandas DataFrame of experimental features and module colors (use mode='dataframe' in get_FeaturesPerModule)
- :param str title: plot title
- :param int width: plot width
- :param int height: plot height
- :return: Plotly object figure.
-
- Example::
-
- plot = plot_intramodular_correlation(MM, FS, feature_module_df, title='Plot', width=1000, height=800):
-
- .. note:: There is a limit in the number of subplots one can make in Plotly. This function limits the number of modules shown to 5.
- """
- figure = {}
- if MM is not None:
- MM = MM.iloc[:, -6]
- MM['modColor'] = MM.index.map(feature_module_df.set_index('name')['modColor'].get)
-
- figure = tools.make_subplots(rows=len(FS.columns), cols=len(MM.columns) - 1, shared_xaxes=False, shared_yaxes=False, vertical_spacing=0.015, horizontal_spacing=0.1, print_grid=True)
-
- figure.layout.template = 'plotly_white'
- layout = dict(width=width, height=height, showlegend=False, title=title)
- figure.layout.update(layout)
-
- axis_dict = {}
- for i, j in enumerate(MM.columns[MM.columns.str.startswith('MM')]):
- n_p = len(FS.columns) * (len(MM.columns)-1)-len(MM.columns[MM.columns.str.startswith('MM')])
- axis_dict['xaxis{}'.format(n_p+i+1)] = dict(title=j, titlefont=dict(size=13))
- print(axis_dict)
- n = 1
- for a, b in enumerate(FS.columns):
- name = b.split(' ')
- if len(name) > 1:
- label = ['
'.join(name[i:i+3]) for i in range(0, len(name), 3)][0]
- else:
- label = name[0]
- axis_dict['yaxis{}'.format(a+n)] = dict(title=label, titlefont=dict(size=13))
- n += len(MM.columns[MM.columns.str.startswith('MM')])-1
-
- annotation = []
- x_axis = 1
- y_axis = 1
- for a, b in enumerate(FS.columns):
- for i, j in enumerate(MM.columns[MM.columns.str.startswith('MM')]):
- name = MM[MM['modColor'] == j[2:]].index
- x = abs(MM[MM['modColor'] == j[2:]][j].values)
- y = abs(FS[FS.index.isin(name)][b].values)
-
- slope, intercept, r_value, p_value, std_err = scp.stats.linregress(x, y)
- line = slope*x+intercept
-
- figure.append_trace(go.Scattergl(x = x,
- y = y,
- text = name,
- mode = 'markers',
- opacity=0.7,
- marker={'size': 7,
- 'color': 'white',
- 'line': {'width': 1.5, 'color': j[2:]}}), a+1, i+1)
-
- figure.append_trace(go.Scattergl(x = x, y = line, mode = 'lines', marker={'color': 'black'}), a+1, i+1)
-
- annot = dict(x = 0.7, y = 0.7,
- xref = 'x{}'.format(x_axis), yref = 'y{}'.format(y_axis),
- text = 'R={:0.2}, p={:.0e}'.format(r_value, p_value),
- showarrow = False)
- annotation.append(annot)
- x_axis += 1
- y_axis += 1
-
-
- figure.layout.update(axis_dict)
- figure.layout.update(annotations = annotation)
-
- return figure
-
-def plot_complex_dendrogram(dendro_df, subplot_df, title, dendro_labels=[], distfun='euclidean', linkagefun='average', hang=0.04, subplot='module colors', subplot_colorscale=[], color_missingvals=True, row_annotation=False, col_annotation=False, width=1000, height=800):
- """
- This function plots a dendrogram with a subplot below that can be a heatmap (annotated or not) or module colors.
-
- :param dendro_df: pandas dataframe containing data used to generate dendrogram, columns will result in dendrogram leaves.
- :param subplot_df: pandas dataframe containing data used to generate plot below dendrogram.
- :param str title: the title of the figure.
- :param list dendro_labels: list of strings for dendrogram leaf nodes labels.
- :param str distfun: distance measure to be used (‘euclidean‘, ‘maximum‘, ‘manhattan‘, ‘canberra‘, ‘binary‘, ‘minkowski‘ or ‘jaccard‘).
- :param str linkagefun: hierarchical/agglomeration method to be used (‘single‘, ‘complete‘, ‘average‘, ‘weighted‘, ‘centroid‘, ‘median‘ or ‘ward‘).
- :param float hang: height at which the dendrogram leaves should be placed.
- :param str subplot: type of plot to be shown below the dendrogram (´module colors´ or ´heatmap´).
- :param list subplot_colorscale: colorscale to be used in the subplot.
- :param bool color_missingvals: if set to `True`, plots missing values as grey in the heatmap.
- :param bool row_annotation: if `True`, adds a color-coded column at the left of the heatmap.
- :param bool col_annotation: if `True`, adds a color-coded row at the bottom of the heatmap.
- :param int width: the width of the figure.
- :param int height: the height of the figure.
- :return: Plotly object figure.
- """
- figure = {}
- dendro_tree = wgcnaAnalysis.get_dendrogram(dendro_df, dendro_labels, distfun=distfun, linkagefun=linkagefun, div_clusters=False)
- if dendro_tree is not None:
- dendrogram = Dendrogram.plot_dendrogram(dendro_tree, hang=hang, cutoff_line=False)
-
- layout = go.Layout(width=width, height=height, showlegend=False, title=title,
- xaxis=dict(domain=[0, 1], range=[np.min(dendrogram['layout']['xaxis']['tickvals'])-6,np.max(dendrogram['layout']['xaxis']['tickvals'])+4], showgrid=False,
- zeroline=True, ticks='', automargin=True, anchor='y'),
- yaxis=dict(domain=[0.7, 1], autorange=True, showgrid=False, zeroline=False, ticks='outside', title='Height', automargin=True, anchor='x'),
- xaxis2=dict(domain=[0, 1], autorange=True, showgrid=True, zeroline=False, ticks='', showticklabels=False, automargin=True, anchor='y2'),
- yaxis2=dict(domain=[0, 0.64], autorange=True, showgrid=False, zeroline=False, automargin=True, anchor='x2'))
-
-
- if subplot == 'module colors':
- figure = tools.make_subplots(rows=2, cols=1, print_grid=False)
-
- for i in list(dendrogram['data']):
- figure.append_trace(i, 1, 1)
-
- shapes = plot_dendrogram_guidelines(dendro_tree, dendrogram)
- moduleColors = get_module_color_annotation(dendro_labels, col_annotation=col_annotation, bygene=True, module_colors=subplot_df, dendrogram=dendrogram)
- figure.append_trace(moduleColors, 2, 1)
- figure['layout'] = layout
- figure.layout.template = 'plotly_white'
- figure['layout'].update({'shapes':shapes,
- 'xaxis':dict(showticklabels=False),
- 'yaxis':dict(domain=[0.2, 1]),
- 'yaxis2':dict(domain=[0, 0.19], title='Module colors', ticks='', showticklabels=False)})
-
-
- elif subplot == 'heatmap':
- if all(list(subplot_df.columns.map(lambda x: subplot_df[x].between(-1,1, inclusive=True).all()))) != True:
- df = wgcnaAnalysis.get_percentiles_heatmap(subplot_df, dendro_tree, bydendro=True, bycols=False).T
- else:
- df = wgcnaAnalysis.df_sort_by_dendrogram(wgcnaAnalysis.df_sort_by_dendrogram(subplot_df, dendro_tree).T, dendro_tree)
-
- heatmap = get_heatmap(df, colorscale=subplot_colorscale, color_missing=color_missingvals)
-
-
- if row_annotation == True and col_annotation == True:
- figure = tools.make_subplots(rows=3, cols=2, specs=[[{'colspan':2}, None],
- [{}, {}],
- [{'colspan':2}, None]], print_grid=False)
- for i in list(dendrogram['data']):
- figure.append_trace(i, 1, 1)
- for j in list(heatmap['data']):
- figure.append_trace(j, 2, 2)
-
- r_annot, c_annot = get_module_color_annotation(list(df.index), row_annotation=row_annotation, col_annotation=col_annotation, bygene=False)
- figure.append_trace(r_annot, 2, 1)
- figure.append_trace(c_annot, 3, 1)
-
- figure['layout'] = layout
- figure.layout.template = 'plotly_white'
- figure['layout'].update({'xaxis':dict(ticks='', showticklabels=False, anchor='y'),
- 'xaxis2':dict(domain=[0, 0.01], ticks='', showticklabels=False, automargin=True, anchor='y2'),
- 'xaxis3':dict(domain=[0.015, 1], ticks='', showticklabels=False, automargin=True, anchor='y3'),
- 'xaxis4':dict(domain=[0.015, 1], ticks='', showticklabels=True, automargin=True, anchor='y4'),
- 'yaxis':dict(domain=[0.635, 1], automargin=True, anchor='x'),
- 'yaxis2':dict(domain=[0.015, 0.635], autorange='reversed', ticks='', showticklabels=True, automargin=True, anchor='x2'),
- 'yaxis3':dict(domain=[0.01, 0.635], autorange='reversed', ticks='', showticklabels=False, automargin=True, anchor='x3'),
- 'yaxis4':dict(domain=[0,0.01], ticks='', showticklabels=False, automargin=True, anchor='x4')})
-
-
-
- elif row_annotation == False and col_annotation == False:
- figure = tools.make_subplots(rows=2, cols=1, print_grid=False)
-
- for i in list(dendrogram['data']):
- figure.append_trace(i, 1, 1)
- for j in list(heatmap['data']):
- figure.append_trace(j, 2, 1)
-
- figure['layout'] = layout
- figure.layout.template = 'plotly_white'
- figure.layout.update({'xaxis':dict(ticktext=np.array(dendrogram['layout']['xaxis']['ticktext']), tickvals=list(dendrogram['layout']['xaxis']['tickvals'])),
- 'yaxis2':dict(autorange='reversed')})
-
- elif row_annotation == True:
- figure = tools.make_subplots(rows=2, cols=2, specs=[[{'colspan':2}, None],
- [{}, {}]], print_grid=False)
- for i in list(dendrogram['data']):
- figure.append_trace(i, 1, 1)
- for j in list(heatmap['data']):
- figure.append_trace(j, 2, 2)
-
- r_annot = get_module_color_annotation(list(df.index), row_annotation=row_annotation, col_annotation=col_annotation, bygene=False)
- figure.append_trace(r_annot, 2, 1)
-
- figure['layout'] = layout
- figure.layout.template = 'plotly_white'
- figure['layout'].update({'xaxis':dict(domain=[0.015, 1], ticktext=np.array(dendrogram['layout']['xaxis']['ticktext']), tickvals=list(dendrogram['layout']['xaxis']['tickvals']), automargin=True, anchor='y'),
- 'xaxis2':dict(domain=[0, 0.010], ticks='', showticklabels=False, automargin=True, anchor='y2'),
- 'xaxis3':dict(domain=[0.015, 1], ticks='', showticklabels=False, automargin=True, anchor='y3'),
- 'yaxis':dict(automargin=True, anchor='x'),
- 'yaxis2':dict(autorange='reversed', ticks='', showticklabels=True, automargin=True, anchor='x2'),
- 'yaxis3':dict(domain=[0, 0.64], ticks='', showticklabels=False, automargin=True, anchor='x3')})
-
- elif col_annotation == True:
- figure = tools.make_subplots(rows=3, cols=1, specs=[[{}], [{}], [{}]], print_grid=False)
-
- for i in list(dendrogram['data']):
- figure.append_trace(i, 1, 1)
- for j in list(heatmap['data']):
- figure.append_trace(j, 3, 1)
-
- c_annot = get_module_color_annotation(list(df.index), row_annotation=row_annotation, col_annotation=col_annotation, bygene=False)
- figure.append_trace(c_annot, 2, 1)
-
- figure['layout'] = layout
- figure.layout.template = 'plotly_white'
- figure['layout'].update({'xaxis':dict(ticktext=np.array(dendrogram['layout']['xaxis']['ticktext']), tickvals=list(dendrogram['layout']['xaxis']['tickvals']), automargin=True, anchor='y'),
- 'xaxis2':dict(ticks='', showticklabels=False, automargin=True, anchor='y2'),
- 'xaxis3':dict(domain=[0, 1], ticks='', showticklabels=False, automargin=True, anchor='y3'),
- 'yaxis':dict(domain=[0.70, 1], automargin=True, anchor='x'),
- 'yaxis2':dict(domain=[0.615, 0.625], ticks='', showticklabels=False, automargin=True, anchor='x2'),
- 'yaxis3':dict(domain=[0, 0.61], autorange='reversed', ticks='', showticklabels=False, automargin=True, anchor='x3')})
-
- return figure