kuroの覚え書き

96の個人的覚え書き

SQLからmatplotlibでグラフを作ってFlaskで表示

@app.route('/')
def index():
    import matplotlib.pyplot
    from matplotlib.backends.backend_agg import FigureCanvasAgg
    import io
    import random

    session = Session()
    q = session.query(Diff).filter(Diff.id <6).filter(Diff.id > 1).all()
    fig, ax = matplotlib.pyplot.subplots()
    ax.set_title(u'test')
    for y in q:
        x_ax = ["cont4", "cont5", "cont6", "sample7", "sample8", "sample9"]
        y_ax = [y.Nb_cont04, y.Nb_cont05, y.Nb_cont06, y.Nb_samp07, y.Nb_samp08, y.Nb_samp09]
        ax.plot(x_ax, y_ax, '--o', label = y.id)
        ax.legend(loc='upper right')

    canvas = FigureCanvasAgg(fig)
    buf = io.BytesIO()
    canvas.print_png(buf)
    data = buf.getvalue()

    response = make_response(data)
    response.headers['Content-Type'] = 'image/png'
    response.headers['Content-Length'] = len(data)
    return response

こんな感じで複数の検索項目をグラフ化。
ax.plot(x_ax, y_ax, '--o', label = y.id)
ax.legend(loc='upper right')
この部分で凡例の配置や、項目名、グラフの線やポイントの形などを色々制御できる。


なお、y軸の数値がintの場合は上のコードでよかったのだが、floatになるとちょっとおかしなことになった。

ValueError: could not convert string to float: "cont4"

というエラーが出てしまう。どうも文字列をFloat型に書き換えようとしてしまってエラーになっている模様。これの解決策として、x軸を一旦なしにして描画(ただしその場合項目が0,1,2...となる)し、あとで文字列へ置き換えてやるコードを追加することになる。

        y_ax = [y.Nb_cont04, y.Nb_cont05, y.Nb_cont06, y.Nb_samp07, y.Nb_samp08, y.Nb_samp09]
        ax.plot(y_ax, '--o', label = y.id)
        matplotlib.pyplot.xticks([0,1,2,3,4,5], ["cont4", "cont5", "cont6", "sample7", "sample8", "sample9"]

こんな感じ。

現状ではグラフを新しいウインドウを開いて表示する形になり、表と見比べるのがやりにくい。表示を同じウィンドウの中に埋め込みたい。

img_data = urllib.parse.quote(data)

return render_template('/rna/exp/index_nb_diff.html', form=form, contents=q, counts=counts, img_data=img_data)

というような感じでurllibでbase64エンコードしてrender_templateでhtmlに引き渡し、templateの方で

<img src="data:image/png:base64,{{ img_data }}"/>

とイメージタグで受け取ると、その場所に埋め込んでもらえるようだ。

とりあえず遺伝子名やGOでSQLに検索をかけてその遺伝子発現パターンを視覚化して評価するアプリが完成した。
次はやはり逆に発現パターンからGOを絞るプログラムが必要だな。ここからはやはりRのおでましかな。