web-dev-qa-db-ja.com

matplotlibの図をHTMLに渡す(フラスコ)

Matplotlibを使用して、Webアプリで図をレンダリングしています。スクリプトを実行しているときだけ、以前にfig.savefig()を使用しました。ただし、HTMLで呼び出すことができるように、実際の ".png"画像を返す関数が必要です。

いくつかの(おそらく不要な)情報:Python Flaskを使用しています。fig.savefig()を使用して、静的フォルダーにFigureを貼り付けてから呼び出しますHTMLですが、毎回やるのではなく、フィギュアを作成し、それから画像を作成し、その画像を返して、HTMLから呼び出すことができれば最適です。

図を作成するコードが機能します。ただし、それは図を返しますが、これは私が推測するHTMLでは機能しません。

ルーティングでdraw_polygonを呼び出す場所は次のとおりです。draw_polygonは図形を返すメソッドです:

@app.route('/images/<cropzonekey>')
def images(cropzonekey):
    fig = draw_polygons(cropzonekey)
    return render_template("images.html", title=cropzonekey, figure = fig)

そして、これが画像を生成しようとしているHTMLです。

<html>
  <head>
    <title>{{ title }} - image</title>
  </head>
  <body>
    <img src={{ figure }} alt="Image Placeholder" height="100">
  </body>
</html>

そして、おそらく推測できるように、ページをロードすると、Image Placeholderしか取得できません。だから、彼らは私が図を送り込んだフォーマットを好まなかった。

誰が図を実際の画像に変えるmatplotlibメソッド/回避策を知っていますか?私はこれらのドキュメント全体にいますが、何も見つかりません。ありがとう!

ところで:図を作成するpythonコードを含める必要があるとは思わなかったが、皆さんがそれを見る必要がある場合、私はそれを含めることができます(質問を混乱させたくありませんでした) )

25
Alex Chumbley

HTMLと画像を2つの異なるルートに分離する必要があります。

_/images/<cropzonekey>_ルートはページを提供するだけで、そのページのHTMLコンテンツには、画像を提供する2番目のルートへの参照があります。

イメージは、savefig()で生成したメモリファイルから独自のルートで提供されます。

私は明らかにこれをテストしませんでしたが、次の例はそのまま機能するか、実際のソリューションにかなり近づくと信じています。

_@app.route('/images/<cropzonekey>')
def images(cropzonekey):
    return render_template("images.html", title=cropzonekey)

@app.route('/fig/<cropzonekey>')
def fig(cropzonekey):
    fig = draw_polygons(cropzonekey)
    img = StringIO()
    fig.savefig(img)
    img.seek(0)
    return send_file(img, mimetype='image/png')
_

_images.html_テンプレートは次のようになります。

_<html>
  <head>
    <title>{{ title }} - image</title>
  </head>
  <body>
    <img src="{{ url_for('fig', cropzonekey = title) }}" alt="Image Placeholder" height="100">
  </body>
</html>
_
30
Miguel

Python3の場合....

DataFrameがあるので、このプロットをFlask ....

そのため、プロットのBase64イメージを作成します。

_    df_week_min_az = pd.DataFrame.from_dict(week_max_az.to_dict(),
                                            orient='index', columns=['min_az'])



    sunalt = df_week_max_angle.plot().get_figure()
    buf = io.BytesIO()
    sunalt.savefig(buf, format='png')
    buf.seek(0)
    buffer = b''.join(buf)
    b2 = base64.b64encode(buffer)
    sunalt2=b2.decode('utf-8')
_

このようにbase64でエンコードされたデータを使用してテンプレートを呼び出します。

return render_template('where.html', form=form, sunalt=sunalt2)

テンプレートの関連部分(画像ビット)は次のようになります。

_ {% if sunalt != None %}

      <h2>Sun Altitude during the year</h2>
    <img src="data:image/png;base64,{{ sunalt }}">
{% endif %}
_

それが誰かを助けることを願っています。

5
Tim Seed
from flask import Flask, send_file
from io import StringIO
import matplotlib.pyplot as plt
from StringIO import StringIO
@app.route('/fig/')
def fig():
      plt.plot([1,2,3,4], [1,2,3,4])
      img = StringIO()
      plt.savefig(img)
      img.seek(0)
      return send_file(img, mimetype='image/png')

他の答えは正しいです、私はちょうど含まれなければならないヘッダーファイルを見せたかったです。このプログラムは単純なグラフを作成し、それをhtmlページに送信します。

1

私はPython 3.x、コードのいくつかの行を変更し、それは私のために働いていました。次のエラーメッセージがありました:"..... object属性がありません 'savefig' "

@app.route('/fig/<cropzonekey>')

def fig(cropzonekey):
    #fig = draw_polygons(cropzonekey)
    fig = plt.plot([1,2,3,4], [1,2,3,4])
    #img = StringIO()
    img = BytesIO()
    #fig.savefig(img)
    plt.savefig(img)
    img.seek(0)
    return send_file(img, mimetype='image/png')
1
Rodolfo Alvarez