我正在尝试利用 pandasai 根据提供的输入生成图表。然后使用 Flask API 公开生成的图像响应。
from pandasai import PandasAI
from pandasai.llm.openai import OpenAI
import pandas as pd
import os
from flask import send_file, request, jsonify
from flask import Flask
import numpy as np #The Python numerical algebra package
import pandas as pd #For working with data frames
import io as io
import matplotlib.pyplot as plt
app = Flask(__name__)
port = int(os.environ.get('PORT', 3000))
@app.route('/gdpChart/')
def getChart():
#Accessing the language model of OpenAI through key
llm = OpenAI(api_token='<<<<<my_api_token>>>>')
#Passing the language model to pandasai
pandas_ai = PandasAI(llm)
df1 = pd.DataFrame({
"country": ["United States", "United Kingdom", "France", "Germany", "Italy", "Spain", "Canada", "Australia", "Japan", "China"],
"gdp": [21400000, 2940000, 2830000, 3870000, 2160000, 1350000, 1780000, 1320000, 516000, 14000000],
"happiness_index": [7.3, 7.2, 6.5, 7.0, 6.0, 6.3, 7.3, 7.3, 5.9, 5.0]
})
# Enter Prompt related to data or Select from Pre-defined for demo purposes.
prompt = 'Plot the piechart of countries showing for each the gpd, using different colors for each bar'
response = pandas_ai.run(df1, prompt=prompt,
is_conversational_answer=False)
# bytes_image = io.BytesIO()
# plt.savefig(bytes_image, format='png')
# bytes_image.seek(0)
# return send_file(bytes_image, mimetype='image/jpeg')
return send_file(response, mimetype='image/jpeg')
if __name__ == '__main__':
app.run(host='0.0.0.0', port=port)
这里,当调用 api url http://localhost:3000/gdpChart 时,pandas_ai.run() 会弹出一个图像。但是,我无法将此图像设置为对 API 的响应。
我的查询是:如何将图像响应(来自 pandasai)设置为 Flaskapi 响应,以便图像将作为响应显示在浏览器中..
问候, 法迪
您可以通过在
save_charts
构造函数中将 True
参数设置为 PandasAI
来保存 PandasAI 生成的任何图表。
pandas_ai = PandasAI(llm, save_charts=True, save_charts_path="resources/")
我通过在提示中逐字地告诉它保存图表来做了类似的事情。然后我提供该文件。
prompt = 'Save as plot.png a plot the piechart of countries showing for each the gpd, using different colors for each bar'
您可以以这样的方式编写提示:返回图形图像的base64,即最后打印图形图像的base64。然后直接将基数 64 发送到前端,并在响应中返回。
resQuery+="''' first clear the previous plt, at last always convert the graph image to base64 value and do not forget to print the Base64 value '''"
res= pandas_ai.run(df, prompt=resQuery)
res=res.decode('utf-8')
return res
在前端你可以轻松地用JS解码base64。
我也做了同样的事情,它对我来说效果很好。而且它的速度也比先保存图表然后通过操作系统读取并进一步发送它要快。
能够做到这一点的关键是将图表保存在特定目录中然后将其复制到静态文件夹中以便flask获取并显示它。在您的后端,您可以通过检查响应的类型来了解 pandasai 何时返回图表。当您的查询涉及生成图表时,响应为“无”。如果您愿意,您可以捕获其他响应类型(例如文本或表格)并呈现它们。 这就是我让它工作的方法:
# Load in the smart df
def getChart():
#Accessing the language model of OpenAI through key
llm = OpenAI(api_token='<<<<<my_api_token>>>>')
#Passing the language model to pandasai
pandas_ai = PandasAI(llm, save_charts_path="path/to/saved_chart")
df1 = pd.DataFrame({
"country": ["United States", "United Kingdom", "France", "Germany", "Italy", "Spain", "Canada", "Australia", "Japan", "China"],
"gdp": [21400000, 2940000, 2830000, 3870000, 2160000, 1350000, 1780000, 1320000, 516000, 14000000],
"happiness_index": [7.3, 7.2, 6.5, 7.0, 6.0, 6.3, 7.3, 7.3, 5.9, 5.0]
})
# Enter Prompt related to data or Select from Pre-defined for demo purposes.
prompt = 'Plot the piechart of countries showing for each the gpd, using different colors for each bar'
response = pandas_ai.run(df1, prompt=prompt,
is_conversational_answer=False)
# When your query involves generating a chart, response is None
# You can catch other response types (like text or table) if you like and present them
if response is None:
try:
shutil.copy(
"path/to/saved_chart/temp_chart.png", "static/temp_chart.png"
)
return render_template(
"home.html",
message="Chart displayed!"
)
except Exception as e:
print(e)
return render_template(
"home.html",
message="Something went wrong! Please try again.",
)
else:
return render_template(
"home.html",
message="Pandas AI didn't return a chart!"
)
请注意temp_chart.png
可能会在不同环境中发生变化,例如在 docker 容器内。确保您使用正确的文件名。 如果您想在 html 页面(例如 home.html)上显示图像:
<!doctype html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<img src="static/temp_chart.png" alt="Graph" style="width:100%">
<p>{{message}}</p>
</body>
</html>