Dash Bio⑨(ニードル プロット)

ニードル プロット

NeedlePlotコンポーネントを使うと、JSON形式のデータを点と線の組み合わせで可視化することができます。

ニードル プロットは、データポイントを横方向のベースラインに接続する垂直線を表示し、指定された値の上と下の両方の値を表示する場合に便利です。

Dash Enterprise - https://dash.plotly.com/dash-bio/needleplot

上記のDash Enterpriseにあるサンプルを参考にして、ニードル プロットを表示してみます。

[ソースコード]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import json
import urllib.request as urlreq
import dash
import dash_bio as dashbio

app = dash.Dash(__name__)

data = urlreq.urlopen(
'https://git.io/needle_PIK3CA.json'
).read().decode('utf-8')

mdata = json.loads(data)

app.layout = dashbio.NeedlePlot(
mutationData=mdata,
rangeSlider=True)

if __name__ == '__main__':
app.run_server(debug=True)

[ブラウザで表示]

ニードルプロットを表示することができました。

ドラッグ操作により表示範囲や表示位置を変えたり、凡例のデータ名をクリックすることによりデータの表示・非表示を切り替えたりすることができます。

Dash Bio⑧(NGL分子を可視化)

NGL分子を可視化

NglMoleculeViewerコンポーネントを使うと、NGL分子を可視化することができます。

Dash Enterprise - https://dash.plotly.com/dash-bio/nglmoleculeviewer

上記のDash Enterpriseにあるサンプルを参考にして、NGL分子を可視化してみます。

[ソースコード]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import dash
import dash_bio as dashbio
from dash import dcc, html
from dash.dependencies import Input, Output
from dash.exceptions import PreventUpdate
import dash_bio.utils.ngl_parser as ngl_parser

app = dash.Dash(__name__)

data_path = "https://raw.githubusercontent.com/plotly/datasets/master/Dash_Bio/Molecular/"

dropdown_options = [
{"label": "1BNA", "value": "1BNA"},
{"label": "MPRO", "value": "MPRO"},
{"label": "PLPR", "value": "PLPR"},
{"label": "5L73", "value": "5L73"},
{"label": "NSP2", "value": "NSP2"}
]

app.layout = html.Div([
dcc.Dropdown(
id="default-ngl-molecule-dropdown",
options=dropdown_options,
placeholder="Select a molecule",
value="1BNA"
),
dashbio.NglMoleculeViewer(id="default-ngl-molecule"),
])

@app.callback(
Output("default-ngl-molecule", 'data'),
Output("default-ngl-molecule", "molStyles"),
Input("default-ngl-molecule-dropdown", "value")
)
def return_molecule(value):

if value is None:
raise PreventUpdate

molstyles_dict = {
"representations": ["cartoon", "axes+box"],
"chosenAtomsColor": "white",
"chosenAtomsRadius": 1,
"molSpacingXaxis": 100,
}

data_list = [ngl_parser.get_data(data_path=data_path, pdb_id=value, color='red',reset_view=True, local=False)]

return data_list, molstyles_dict

if __name__ == '__main__':
app.run_server(debug=True)

[ブラウザで表示]

NGL分子を可視化することができました。

左クリックでドラッグをすると角度を変えて表示することができ、右クリックでドラッグすると位置を変えて表示することができます。

またスクロールの上下をすることによって拡大・縮小表示をすることができます。

Dash Bio⑦(SMILES記法を可視化)

SMILES記法を可視化

Jsmeコンポーネントを使うと、SMILES記法で書かれた文字列を可視化することができます。

SMILES記法とは、分子の化学構造をASCII符号の英数字で文字列化した、構造的に曖昧性の無い表記方法です。

Dash Enterprise - https://dash.plotly.com/dash-bio/jsme

上記のDash Enterpriseにあるサンプルを参考にして、SMILES記法で書かれた文字列を可視化してみます。

[ソースコード]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import dash
import dash_bio as dashbio
import dash_html_components as html

app = dash.Dash(__name__)

app.layout = html.Div([
dashbio.Jsme(
smiles='O=C(Nc1cccc(Cl)c1)c3cncc4nnc(c2ccc(OC(F)F)cc2)n34',
),
])

if __name__ == '__main__':
app.run_server(debug=True)

[ブラウザで表示]

SMILES記法で書かれた文字列を可視化することができました。

Dash Bio⑥(分子構造を可視化)

分子構造を可視化

Speckコンポーネントを使うと、分子構造を可視化することができます。

Dash Enterprise - https://dash.plotly.com/dash-bio/speck

上記のDash Enterpriseにあるサンプルを参考にして、メタンの分子構造を可視化してみます。

[ソースコード]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import urllib.request as urlreq
import dash
import dash_bio as dashbio
from dash_bio.utils import xyz_reader

app = dash.Dash(__name__)

data = urlreq.urlopen(
'https://git.io/speck_methane.xyz'
).read().decode('cp932')

data = xyz_reader.read_xyz(datapath_or_datastring=data, is_datafile=False)

app.layout = dashbio.Speck(data=data)

if __name__ == '__main__':
app.run_server(debug=True)

[ブラウザで表示]

メタン分子構造を可視化することができました。

マウスをドラッグをすると角度を変えて表示することができます。

また Ctrl+スクロール上下 で拡大・縮小表示をすることもできます。

Dash Bio⑤(核酸/アミノ酸配列を可視化)

核酸/アミノ酸配列を可視化

AlignmentChartコンポーネントを使うと、FASTA形式やClustal形式のデータから核酸またはアミノ酸の配列を可視化することができます。

Dash Enterprise - dash_bio.AlignmentChart Examples and Reference

上記のDash Enterpriseにあるサンプルを参考にして、細胞性腫瘍(cellular tumor)を可視化してみます。

[ソースコード]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import dash
import dash_bio as dashbio
from dash import html
import urllib.request as urlreq
from dash.dependencies import Input, Output

app = dash.Dash(__name__)

data = urlreq.urlopen(
'https://git.io/alignment_viewer_p53.fasta'
).read().decode('utf-8')

app.layout = html.Div([
dashbio.AlignmentChart(
data=data
)
])

if __name__ == '__main__':
app.run_server(debug=True)

[ブラウザで表示]

細胞性腫瘍(cellular tumor)を可視化することができました。

グラフをドラッグすると位置を変えて表示したり、表示範囲を変更して表示したりすることができます。

Dash Bio④(生体分子構造)

生体分子構造を可視化

Molecule3dViewerコンポーネントを使うと生体分子構造を3次元に可視化することができます。

Dash Enterprise - dash_bio.Molecule3dViewer Examples and Reference

上記のDash Enterpriseにあるサンプルを参考にして、生体分子構造を3次元に可視化してみます。

[ソースコード]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import dash
import dash_bio as dashbio
from dash import html
from dash_bio.utils import PdbParser, create_mol3d_style
from dash.dependencies import Input, Output

app = dash.Dash(__name__)

parser = PdbParser('https://git.io/4K8X.pdb')

data = parser.mol3d_data()
styles = create_mol3d_style(
data['atoms'], visualization_type='cartoon', color_element='residue'
)

app.layout = html.Div([
dashbio.Molecule3dViewer(
id='dashbio-default-molecule3d',
modelData=data,
styles=styles
)
])

if __name__ == '__main__':
app.run_server(debug=True)

[ブラウザで表示]

生体分子構造を3次元に可視化することができ、ドラッグするといろいろな角度で表示することができました。

また Ctrl+スクロール上下 で拡大・縮小表示することもできます。

Dash Bio③(サーコスプロットの外側にヒストグラム表示)

サーコスプロットの外側にヒストグラム表示

サーコスプロットの外側にヒストグラムを表示してみます。

グラフの種類に‘HISTOGRAM’を設定するとヒストグラムを表示することができます。(24行目)

[ソースコード]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import json
import urllib.request as urlreq

import dash
import dash_bio as dashbio
from dash import html, dcc
from dash.dependencies import Input, Output, State

app = dash.Dash(__name__)

data = urlreq.urlopen(
"https://git.io/circos_graph_data.json"
).read().decode("utf-8")

circos_graph_data = json.loads(data)

app.layout = html.Div(
[
dashbio.Circos(
id="circos",
layout=circos_graph_data["GRCh37"],
tracks=[
{
'type':'HISTOGRAM',
'data':circos_graph_data["histogram"],
'config':{ # ヒストグラムを外側に表示
'innerRadius':300,
'outerRadius':500
}
}
]
)
]
)

if __name__ == "__main__":
app.run_server(debug=True)

ヒストグラムを外側に表示するためにconfig属性を設定する必要はないのですが、デフォルトだとヒストグラムが小さく見づらいので、ヒストグラムが見やすくなるようにconfig属性を設定します。

‘innerRadius’には外側の半径、‘outerRadius’には外側の半径を設定しています。(26~29行目)

[ブラウザで表示]

サーコスプロットの外側にヒストグラムを表示することができました。

Dash Bio②(サーコスプロットの内側にヒストグラム表示)

サーコスプロットの内側にヒストグラム表示

サーコスプロットの内側にヒストグラムを表示してみます。

グラフの種類に‘HISTOGRAM’を設定するとヒストグラムを表示することができます。(24行目)

[ソースコード]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import json
import urllib.request as urlreq

import dash
import dash_bio as dashbio
from dash import html, dcc
from dash.dependencies import Input, Output, State

app = dash.Dash(__name__)

data = urlreq.urlopen(
"https://git.io/circos_graph_data.json"
).read().decode("utf-8")

circos_graph_data = json.loads(data)

app.layout = html.Div(
[
dashbio.Circos(
id="circos",
layout=circos_graph_data["GRCh37"],
tracks=[
{
'type':'HISTOGRAM',
'data':circos_graph_data["histogram"],
'config':{ # ヒストグラムを内側に表示
'innerRadius':40,
'outerRadius':230
}
}
]
)
]
)

if __name__ == "__main__":
app.run_server(debug=True)

ヒストグラムを内側に表示するためにconfig属性に描画する位置を指定する必要があります。

‘innerRadius’には内側の半径、‘outerRadius’には外側の半径を設定します。(26~29行目)

[ブラウザで表示]

サーコスプロットの内側にヒストグラムを表示することができました。

Dash Bio①(インストール/サーコスプロット)

Dash Bioコンポーネントを使うと、バイオインフォマティクスのデータを短いコードで可視化、分析することができます。

Dash Bioのインストール

Dash Bioをインストールするためには、下記のコマンドを実行します。

[コマンド]

1
pip install dash-bio

Windows環境で実行していてMicrosoft Visual C++ 14.0 or greater is required.というエラーが発生した場合、下記のサイトを参考にMicrosoft C++ Build Toolsをインストールしてください。

参考サイト - 「Microsoft Visual C++ 14.0 or greater is required.」が出た場合の対処方法

サーコスプロット

Circosコンポーネントを使ってデータ間の繋がりを円形で可視化します。

サーコスプロットは円形のレイアウトで、要素間の関係を可視化することができ、バイオインフォマティクスの分野以外にもいろいろな分野で利用できます。

[ソースコード]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import dash
import dash_bio as dashbio
import dash_html_components as html

app = dash.Dash(__name__) # Dashインスタンスを生成

# レイアウト作成
app.layout = html.Div(
[
dashbio.Circos(
# 要素
layout=[
{'id':'1', 'label':'1', 'color':'yellow', 'len':100},
{'id':'2', 'label':'2', 'color':'skyblue','len':180},
{'id':'3', 'label':'3', 'color':'purple', 'len':250},
{'id':'4', 'label':'4', 'color':'pink', 'len':200},
{'id':'5', 'label':'5', 'color':'lime', 'len': 70}
],
# 要素の関係
tracks=[
{
# グラフの種類
'type': 'CHORDS',
# 要素間のデータ
'data':[
{
'source':{'id':'1', 'start':50, 'end':100},
'target':{'id':'3', 'start':30, 'end':50},
},
{
'source':{'id':'1', 'start':30, 'end':50},
'target':{'id':'4', 'start': 0, 'end':70},
},
{
'source':{'id':'2', 'start':100, 'end':150},
'target':{'id':'5', 'start': 30, 'end': 50},
},
{
'source':{'id':'3', 'start':100, 'end':150},
'target':{'id':'3', 'start': 0, 'end': 30},
}
],
'opacity':0.8,
'color':{'name':'color'},
'config':{
# マウスオーバー時に表示するデータ
'tooltipContent':{
'source':'source',
'sourceID':'id',
'target':'target',
'targetID':'id',
'targetEnd':'end'
}
}
}
]
)
]
)

if __name__ == '__main__':
app.run_server(debug=True) # アプリケーションを起動

Circosコンポーネントは、引数 layoutに外側の円の要素、引数 tracksに要素同士の関連データを渡してグラフを作成します。

作成するグラフの種類は引数 tracksに渡す辞書のキー‘type’に値を設定します。

各属性の主な設定方法は以下の通りです。

  • layout (辞書:必須) サーコスプロットの外側の部分を設定
    • id (文字列:必須) ブロックID
    • label (文字列:必須) ブロックのラベル
    • color (文字列:必須) ブロックの色
    • len (数値:必須) ブロックの長さ
  • tracks (辞書:任意) トラックの設定
    • id (文字列:認知) トラックのデータID
    • data (リスト:必須) トラックのデータ(JSONデータ)
    • type (文字列:任意) トラックの種類
    • config (辞書:任意) トラックのレイアウト

[ブラウザで表示]

サーコスプロットが表示され、円形のレイアウトでそれぞれの要素間の繋がりを確認することができます。

Dash 第62回(DashCanvas 画像の切り抜き)

DashCanvas 画像の切り抜き

画像を表示したキャンバス上で輪郭を指定して、その範囲の画像の切り抜きを行ってみます。

superpixel_color_segmentation関数を使って、ペンシルツールで指定した輪郭の内側を切り抜いて表示します。

[ソースコード]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import dash
import dash_html_components as html
import numpy as np
from dash.dependencies import Input, Output
from dash.exceptions import PreventUpdate
from dash_canvas import DashCanvas
from dash_canvas.utils import (array_to_data_url, image_string_to_PILImage,
parse_jsonstring, superpixel_color_segmentation)
from skimage import io

filepath = 'cherry.png'
image = array_to_data_url(io.imread(filepath))
app = dash.Dash(__name__) # Dashインスタンスを生成

# レイアウト作成
app.layout = html.Div(
[
html.Div(
[
DashCanvas(
id='image1',
image_content=image,
width=400,
lineWidth=5,
lineColor='lime',
goButtonTitle='remove'
)
],
),
html.Div(
[html.Img(id='image2',width=400)]
)
]
)

# 選択した長方形の範囲をテーブルに表示するコールバック
@app.callback(
Output('image2', 'src'),
Input('image1', 'json_data'),
Input('image1', 'image_content')
)
def remove_background(json_data, image):
if json_data:
if image: # imageが値を持つ場合
# もとの画像をnumpy.ndarrayに変換する
image_array = image_string_to_PILImage(image)
image_array = np.asarray(image_array)
else:
image_array = io.imread(filepath)
# 画像のarrayサイズを変数shapeに代入する
shape = image_array.shape[:2]

# アノテーションのjsonデータをパースし、ブール値に変換する
try:
mask = parse_jsonstring(json_data, shape=shape)
except IndexError:
raise PreventUpdate

if mask.sum() > 0:
seg = superpixel_color_segmentation(image_array, mask)
else:
seg = np.ones(shape)
filled_image = np.copy(image_array)
filled_image[np.logical_not(seg)] = np.array([255, 255, 255], dtype='uint8')
return array_to_data_url(filled_image)
else:
raise PreventUpdate

if __name__ == '__main__':
app.run_server(debug=True) # アプリケーションを起動

画像の背景を取り除く処理はremove_backgroundコールバック関数で行っています。(42行目)

入力項目は、画像へのアノテーションデータをもつjson_data属性と、画像データ文字列のimage_contents属性です。

処理の流れは以下の通りです。

  1. 画像データを取得し、numpy.ndarray型に変換する。(46~47行目)
  2. 画像へのアノテーションデータと画像の形状からブール値に変換する。(55行目)
  3. マスク処理したデータが存在する場合、superpixel_color_segmentation関数を使って類似した色を分割する。(60行目)
  4. 画像から3の結果を反転した領域を、白色(255.255.255)にする。(64行目)
  5. 処理した画像(numpy.ndarray)を文字列に変換する。(65行目)

[ブラウザで表示]

対象を選択しremoveボタンを押すと、選択範囲が切り抜かれてツールの下に表示される・・・・はずなんですがはっきり切り抜きできませんでした。

2回、3回同じ範囲を選択するとうまく切り抜かれていくようです。

改善の余地がありそうですね😥