最初に結論
- (バックエンド)BytesIOを使ってmatplotlibの画像のByteデータを取得する
- (バックエンド)
media_type="/image/png"
で送信 - (クライアント)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オブジェクトのフィールドの項目の一つとして送信することが一般的なようです。