趣味で計算流砂水理

趣味で計算流砂水理 Computational Sediment Hydraulics for Fun Learning

数値計算とか河川工学とかプログラミングのことを書いています

MENU

備忘録:Pyviz Panelでファイルインプット、アウトプットを実装する

スポンサーリンク

f:id:SedimentHydraulics:20210729125901g:plain

Panelでファイルインプット、アウトプットを実装しました。

これがあるとWebアプリを作るときに活用できます。

でも、なかなか癖が強いですね。


今回はjsonファイルを例に取り扱っています。 テキストファイルと画像ファイルは、同様に実装できるようです。

ポイントは、

  • ファイル出力にStringIO()を使う
  • ファイル入力後に表示されるオブジェクトは事前に空の配列を準備しておき、callbackで更新する。

です。

開発者のPhilipp RudigerさんがPanelの開発に力を入れているようなので仕様は今後変わる可能性が高いです。(PyDev of the Week: Philipp Rudiger - Mouse Vs Python参照)

import pandas as pd
from io import StringIO
import panel as pn
pn.extension()
pn.__version__
#'0.11.3'
def getsio(val):
    df = pd.read_json(val)
    sio = StringIO()
    d = df.to_json(sio)
    sio.seek(0)
    return sio

file_input = pn.widgets.FileInput(accept='.json')
obj = pn.Column(file_input, '')

def update(event):
    if file_input.value is not None:
        file_output = pn.widgets.FileDownload(getsio(file_input.value), embed=True, filename='output.json')
        obj[-1] = file_output
        
file_input.param.watch(update, 'value')
obj.servable()

補足:geopandasでgoejsonを取り扱う場合

String型ではなく、Byte型になるようなので上記のgetsio関数を以下のようにする必要があるようです。

from io import StringIO, BytesIO

def getsio(val):
    df = gpd.read_file(val.decode('utf-8'))
    sio = BytesIO()
    d = df.to_file(sio, driver='GeoJSON', encoding='UTF-8')
    sio.seek(0)
    return sio

参考サイト