LoginSignup
5
6

More than 1 year has passed since last update.

Pythonバックエンドでmatplotlibで描画された画像をクライアントサイド(React)に表示する方法

Posted at

最初に結論

  1. (バックエンド)BytesIOを使ってmatplotlibの画像のByteデータを取得する
  2. (バックエンド)media_type="/image/png"で送信
  3. (クライアント)axiosなどで、画像データを含むResponseを取得し、タグのsrcに、受け取った画像のByteデータオブジェクトを指定する

以下、サンプルコードを示します。

バックエンド(FastAPI)

import io
from fastapi import FastAPI, Response
import numpy as np
import matplotlib.pyplot as plt

app = FastAPI()

@app.get('/my/backend-api/endpoint')
def plot_png():
    # データの生成
    x = np.arange(0, 10, 0.1)
    y = np.sin(x)
    # グラフの描画
    fig, ax = plt.subplots()
    ax.plot(x, y)
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    # グラフを画像ファイルに保存
    png_output = io.BytesIO()
    fig.savefig(png_output, format='png')
    # 画像ファイルをクライアントに送信
    png_output.seek(0)
    return Response(content=png_output, media_type="/image/png")

hypercorn main:app --reloadでFastAPIサーバを起動します。

クライアント(React)

コンポーネントだけ記述します。useState, useEffectを用いて初回レンダリング時に画像を取得してimageDataという変数に画像データを格納するコードになっています。

import React, { useState, useEffect} from 'react';
import axios from 'axios';

const ImageComponent = () => {
  const [imageData, setImageData] = useState(null);

  useEffect(() => {
    const fetchData = async () => {
      const result = await axios.get('/your/backend-api/endpoint');
      setImageData(result.data);
    };

    fetchData();
  }, []);

  return (
    <div>
      {imageData && (
        <img src={imageData} alt="wordcloud"/>
      )}
    </div>
  );
}

export default ImageComponent;

以上、matplotlibの画像をAPIで送信してレンダリングするまでの流れを簡単なサンプルコードと共に紹介しました。

ちなみに、以上で紹介した内容はAPIのレスポンスが画像のみの場合ですが、他にテキスト情報と共に返送したい場合は、Base64エンコーディングで画像データをシリアル化(=データ形式を変換すること)して、JSONオブジェクトのフィールドの項目の一つとして送信することが一般的なようです。

5
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6