Dash 第59回(DashCanvasクラスの属性)

DashCanvasクラスの属性

DashCanvasクラスの属性を一覧に表します。

属性 データ型 内容
id 文字列 コンポーネントのIDを設定。
image_content 文字列 PNGまたはJPEGフォーマットの画像データ文字列を設定。
array_to_data_url関数を用いて生成する。
zoom 数値 画像の拡大を設定。
width 数値 キャンバスの横幅を設定。
height 数値 キャンバスの高さを設定。
scale 数値 キャンバスの横幅と画像の横幅の縮尺比を設定。
tool ‘pencil’
‘pen’
‘circle’
‘rectangle’
‘select’
‘line’
描画ツールの初期値を設定。
lineWidth 数値 ペンシルモード時の線幅を設定。
lineColor 文字列 ペンシルモード時の線の色、色名、RGB、RGBAを指定可能。
goButtonTitle 文字列 Saveボタンのタイトルを設定。
filename 文字列 ロードする画像ファイル名(URL文字列)を設定。
trigger 数値 Saveボタンが押された回数データを保持。
json_data 文字列 アノテーションの内容を保持。
hide_buttons ‘pencil’,’zoom’などのリスト型 非表示にする描画ツールを指定。

Dash 第58回(DashCanvas アノテーション表示)

アノテーション表示

json_data属性を使って、キャンバスのアノテーションの内容を表示するアプリケーションを作成します。

レイアウトとしてDashCanvasコンポ―ネントの下に、アノテーションの内容を表示するDivコンポーネントを配置します。(10行目)

[ソースコード]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import json
import dash
import dash_html_components as html
from dash.dependencies import Input, Output
from dash_canvas import DashCanvas

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

# レイアウト作成
app.layout = html.Div([DashCanvas(id='canvas1'), html.Div(id='div1')])

@app.callback(
# 入力項目にID'canvas1'のjson_data属性を設定
Output('div1', 'children'),
Input('canvas1', 'json_data')
)
def show_json(json_data):
if json_data: # json_data属性にデータが存在するかどうか
return json.dumps(json_data) # json_dataを文字列にして返す
else:
raise dash.exceptions.PreventUpdate # コールバックを更新しない

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

コールバック関数では、出力項目をDivコンポーネントのchildren属性、入力項目をDashCanvasコンポーネントのjson_data属性としています。(14~15行目)

json_data属性にデータがある場合、json_data属性の値を返し、データがない場合はコールバックの更新を行いません。(18~21行目)

[ブラウザで表示]

キャンバスに線を描画し、Saveボタンをクリックするとアノテーションの内容が表示されることを確認できます。

Dash 第57回(DashCanvas)

DashCanvasコンポーネントは、画像編集ツールをもつキャンバスです。

キャンバス上に画像を表示し、アノテーションを用いて画像処理をすることができます。

インストール

DashCanvasコンポーネントを使うためには、下記のコマンドを実行しインストールを行います。

[コマンド]

1
pip install dash-canvas

DashCanvasサンプルコード

デフォルト設定のDashCanvasコンポーネントを作成するコードは下記の通りです。

[ソースコード]

1
2
3
4
5
6
7
import dash
from dash_canvas import DashCanvas

app = dash.Dash(__name__) # Dashインスタンスを生成
app.layout = DashCanvas()
if __name__ == '__main__':
app.run_server(debug=True) # アプリケーションを起動

[ブラウザで表示]

線や枠を描画したり、移動・拡大・縮小などができます。

編集ツール右端のSaveボタンでは、画像の保存ではなくDashCanvasコンポーネントのjson_data属性の更新を行います。

json_data属性は描き込みツールを使って描いたアノテーションのデータをもつ属性で、データはJSON形式で保存されます、

Dash 第56回(テーブルデータを地図に表示)

テーブルデータを地図に表示

テーブル上の位置データを地図上に表示します。

地図を表示するためにmapboxよりアクセストークンを取得しておく必要があります。(12行目で設定)

[ソースコード]

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
import dash
import dash_core_components as dcc
import dash_html_components as html
import dash_table
import pandas as pd
import plotly.express as px
from dash.dependencies import Input, Output

df = pd.read_csv('401307compatibleformatshelter.csv', encoding='cp932')

# mapboxのアクセストークンを設定
px.set_mapbox_access_token('<<mapboxで取得したトークン>>')

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

app.layout = html.Div(
[
html.Div(
[
html.H2('避難所マップ'),
dash_table.DataTable(
id='table1',
# セルサイズの設定
style_cell={
'textAliign':'center', # テキストを中央寄せ
'maxWidth':'80px', # 最大横幅
'minWidth':'80px', # 最小横幅
'whiteSpace':'normal' # 文字を折り返して表示
},
fixed_rows={'headers':True}, # 縦スクロール時にヘッダーを固定
columns=[{'name':col, 'id':col} for col in df.columns],
data=df.to_dict('records')
)
]
),
dcc.Graph(id='map1')
]
)

@app.callback(
Output('map1', 'figure'),
Input('table1', 'columns'),
Input('table1', 'derived_virtual_data')
)
def update_map(columns, rows):
df = pd.DataFrame(rows, columns=[c['name'] for c in columns])
return px.scatter_mapbox(
df,
lat='緯度',
lon='経度',
zoom=10,
hover_data=['名称', '名称かな表記', '住所表記']
)

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

コールバック関数には、テーブルの引数columnsとderived_virtual_dataを入力としています。

derived_virtual_dataは、テーブルの全ページデータです。

update_map関数では、列名と全データからDataFrameを作成し、そのDataFrameをscatter_mapbox関数に設定し、地図上に散布図を描画したfigureを返しています。(46~53行目)

[ブラウザで表示]

テーブルの位置データが地図上に散布図として描画されていることを確認できました。

Dash 第55回(テーブルのソートとエクスポート)

テーブルのソートとエクスポート

DataTableコンポーネントには、属性を設定しソートやエクスポートを可能にすることができます。

  • sort_action属性
    ‘native’を設定すると、項目名に上下マークが表示されソート可能になる。(28行目)
    ‘custom’を設定すると、コールバックを使ったカスタマイズが可能になる。
  • sort_mode属性
    ‘single’を設定すると、1つの列のソートが可能になる。
    ‘multi’を設定すると、複数列のソートが可能になる。(29行目)
  • export_format属性
    ‘csv’を設定すると、テーブルに表示されているデータをCSVファイルでダウンロードできるようになる。(30行目)

[ソースコード]

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
import dash
import dash_html_components as html
import dash_table
import pandas as pd

df = pd.read_csv('401307compatibleformatshelter.csv', encoding='cp932')

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

app.layout = html.Div(
[
dash_table.DataTable(
# セルサイズの設定
style_cell={
'textAliign':'center', # テキストを中央寄せ
'maxWidth':'80px', # 最大横幅
'minWidth':'80px', # 最小横幅
'whiteSpace':'normal' # 文字を折り返して表示
},
fixed_rows={'headers':True}, # 縦スクロール時にヘッダーを固定
style_table={'minWidth':'100%'}, # テーブル全幅表示
columns=[{'name':col, 'id':col} for col in df.columns],
data=df.to_dict('records'),
editable=True,
filter_action="native",
row_deletable=True,
row_selectable='multi',
sort_action='native', # 列のソートを可能に
sort_mode='multi', # 複数列のソートを可能に
export_format='csv' # エクスポートの設定
)
]
)

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

[ブラウザで表示]

項目名の左に表示されている上下マークをクリックすると列をソートすることができます。

また、テーブルの左上に表示されているexportボタンをクリックすると、表示されているデータをCSVファイルでダウンロードできます。

Dash 第54回(テーブルの行削除と行選択)

テーブルの行削除と行選択

DataTableコンポーネントには、属性を設定し行の削除や行の選択を可能にすることができます。

row_deletable属性にTrueを設定すると行の先頭に×マークが表示され行の削除ができるようになります。(26行目)

またrow_selectable属性に‘single’を指定すると行を1つ選択することができるようになり、‘multi’を指定すると行を複数選択することができようになります。(27行目)

[ソースコード]

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
import dash
import dash_html_components as html
import dash_table
import pandas as pd

df = pd.read_csv('401307compatibleformatshelter.csv', encoding='cp932')

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

app.layout = html.Div(
[
dash_table.DataTable(
# セルサイズの設定
style_cell={
'textAliign':'center', # テキストを中央寄せ
'maxWidth':'80px', # 最大横幅
'minWidth':'80px', # 最小横幅
'whiteSpace':'normal' # 文字を折り返して表示
},
fixed_rows={'headers':True}, # 縦スクロール時にヘッダーを固定
style_table={'minWidth':'100%'}, # テーブル全幅表示
columns=[{'name':col, 'id':col} for col in df.columns],
data=df.to_dict('records'),
editable=True,
filter_action="native",
row_deletable=True, # 行の消去を可能に
row_selectable='multi' # 複数行の選択を可能に
)
]
)

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

[ブラウザで表示]

行先頭の×マークをクリックすると行が削除され、チェックボックスをクリックすると複数行を選択することができます。

Dash 第53回(テーブルの編集とフィルター)

テーブルの編集とフィルター

DataTableコンポーネントには、属性を設定しセルの編集機能やフィルター機能を追加することができます。

editable属性にTrueを設定すると全てのセルが編集可能になります。(24行目)

またfilter_action属性に‘native’を設定すると、フィルタリングができるようになります。(25行目)

[ソースコード]

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
import dash
import dash_html_components as html
import dash_table
import pandas as pd

df = pd.read_csv('401307compatibleformatshelter.csv', encoding='cp932')

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

app.layout = html.Div(
[
dash_table.DataTable(
# セルサイズの設定
style_cell={
'textAliign':'center', # テキストを中央寄せ
'maxWidth':'80px', # 最大横幅
'minWidth':'80px', # 最小横幅
'whiteSpace':'normal' # 文字を折り返して表示
},
fixed_rows={'headers':True}, # 縦スクロール時にヘッダーを固定
style_table={'minWidth':'100%'}, # テーブル全幅表示
columns=[{'name':col, 'id':col} for col in df.columns],
data=df.to_dict('records'),
editable=True, # セルを編集可能に
filter_action="native" # フィルタリングを可能に
)
]
)

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

[ブラウザで表示]

選択したセルに対して、編集ができるようになっています。

またフィルタリングエリアに入力すると、その入力値を含んだデータだけが表示されます。

Dash 第52回(テーブルの表示幅変更とヘッダー固定表示)

テーブルの表示幅変更とヘッダー固定表示

前回記事ではCSVファイルを読み込んでテーブルに表示しました。

今回はそのテーブルのスタイルを設定します。

まずセルの横幅を均等にするため、‘maxWidth’と‘minWidth’に同じ値を設定します。(16~17行目)

次にセルの内容を折り返すために、‘whiteSpace’に‘normal’を設定します。(18行目)

行ヘッダーを固定するため引数 fixed_rowsに、キーが‘headers’、値がTrueである辞書データを設定します。(20行目)

最後に、引数 style_tableに100%を設定し、テーブルに縦スクロールと横スクロールが表示されるようにします。(21行目)

[ソースコード]

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
import dash
import dash_html_components as html
import dash_table
import pandas as pd

df = pd.read_csv('401307compatibleformatshelter.csv', encoding='cp932')

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

app.layout = html.Div(
[
dash_table.DataTable(
# セルサイズの設定
style_cell={
'textAliign':'center', # テキストを中央寄せ
'maxWidth':'80px', # 最大横幅
'minWidth':'80px', # 最小横幅
'whiteSpace':'normal' # 文字を折り返して表示
},
fixed_rows={'headers':True}, # 縦スクロール時にヘッダーを固定
style_table={'minWidth':'100%'}, # テーブル全幅表示
columns=[{'name':col, 'id':col} for col in df.columns],
data=df.to_dict('records')
)
]
)

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

[ブラウザで表示]

セルの横幅が均等で、セルの内容が折り返して表示されています。

また、縦横にスクロールが表示されており、縦にスクロールしてもヘッダーが固定して表示されることを確認できます。

Dash 第51回(CSVファイルをテーブル表示)

CSVファイルをテーブル表示

今回は、CSVファイルの内容をテーブルに表示してみます。

CSVファイルは下記のURLからダウンロードします。

ckan - 福岡市 避難場所・避難所(共通フォーマット)

CSVファイルをテーブルに表示するソースは下記の通りです。

[ソースコード]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import dash
import dash_html_components as html
import dash_table
import pandas as pd

df = pd.read_csv('401307compatibleformatshelter.csv', encoding='cp932')

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

app.layout = html.Div(
[
dash_table.DataTable(
columns=[{'name':col, 'id':col} for col in df.columns],
data=df.to_dict('records')
)
]
)

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

処理フローは以下の通りです。

  1. read_csv関数でCSVファイルを読み込む。(6行目)
  2. DataTableコンポーネントの引数 columnsに列名を設定する。(13行目)
  3. DataTableコンポーネントの引数 dataに値を設定する。(14行目)

[ブラウザで表示]

CSVファイルをテーブルに表示することができました。

Dash㊿(DataTableコンポーネント 要素ごとにスタイル設定)

要素ごとにスタイル設定

今回は、style_《target》_conditional属性を使って、条件に応じたスタイルの設定を行います。

  • style_cell_conditional
    列全体のスタイルを設定します。
    IDが’number’の列にフォントサイズと背景色を設定しています。(22~28行目)
  • style_header_conditional
    ヘッダー部のスタイルを設定します。
    IDが’area’の列のヘッダーに中央揃えと横幅を設定し、IDが’tsuyuiri’の列のヘッダーに背景色を設定しています(31~34行目)
  • style_data_conditional
    データ部のスタイルを設定します。
    偶数行に背景色を設定し、’number’が3より大きい’tsuyuiri’のデータの背景色を設定しています。(37~43行目)

[ソースコード]

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
import dash
import dash_table

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

app.layout = dash_table.DataTable(
columns=[
{'name':'No.', 'id':'number'},
{'name':'地域', 'id':'area'},
{'name':'梅雨入り', 'id':'tsuyuiri'}
],
data=[
{'number':0, 'area':'沖縄地方', 'tsuyuiri':'5/17'},
{'number':1, 'area':'九州南部', 'tsuyuiri':'5/31'},
{'number':2, 'area':'九州北部', 'tsuyuiri':'6/25'},
{'number':3, 'area':'四国地方', 'tsuyuiri':'6/27'},
{'number':4, 'area':'中国地方', 'tsuyuiri':'6/27'},
{'number':5, 'area':'近畿地方', 'tsuyuiri':'6/28'}
],

# 列全体のスタイル
style_cell_conditional=[
{
'if':{'column_id':'number'},
'fontSize':16,
'backgroundColor':'#FFEEE0'
}
],

# ヘッダー部のスタイル
style_header_conditional=[
{'if':{'column_id':'area'}, 'textAlign':'center', 'width':120},
{'if':{'column_id':'tsuyuiri'}, 'backgroundColor':'#FBFFB9'}
],

# データ部のスタイル
style_data_conditional=[
{'if':{'row_index':'odd'}, 'backgroundColor':'#FBFFB9'},
{
'if':{'column_id':'tsuyuiri', 'filter_query':'{number} > 3'},
'backgroundColor':'#41D3B0'
}
],

)

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

[ブラウザで表示]

条件に指定した通りにスタイルが設定されていることが確認できました。