如何在Django模板中正确渲染Python seaborn生成的统计图表
问题原因
你当前直接向Django模板传递了seaborn的绘图对象,模板无法直接解析该类型对象,只会输出它的字符串描述,因此无法展示实际图表。你可以将图表转为base64编码的PNG图片直接嵌入模板,无需额外存储静态文件,适合实时统计图表的场景,操作步骤如下:
步骤1:修改views.py代码
首先导入所需依赖,调整绘图函数的返回值为base64编码的图片字符串:
# 顶部导入依赖,注意matplotlib.use('Agg')必须放在pyplot导入之前,避免无GUI环境报错 import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt import io import base64 import seaborn as sns # 调整绘图函数 def booking_hour_plot(): qs = bookings_today() df = read_frame(qs) # 新建画布避免多次绘图叠加 plt.figure() # 注意:此处需要补充你要统计的x轴字段,比如存储预订时段的hour字段 sns.countplot(data=df, x='替换为你实际要统计的字段名') # 将图表写入字节流 buffer = io.BytesIO() plt.savefig(buffer, format='png', bbox_inches='tight') # bbox_inches参数避免坐标轴标签被截断 buffer.seek(0) # 转为base64编码 image_png = buffer.getvalue() graph_base64 = base64.b64encode(image_png).decode('utf-8') buffer.close() # 清空画布,避免后续绘图受影响 plt.close() return graph_base64 # 原render_stats_page函数无需修改,仍按原有逻辑传递booking_hour_plot参数即可 def render_stats_page(request): #general info user_count = total_users_until_now() cancel_rate = activity_cancel_rate() #activity/booking details activity_set = activities_today() booking_set = bookings_today() plot = booking_hour_plot() return render(request, "stats.html", {'name':'Avonmore Statistics', 'total_user':int(user_count), 'cancel_rate': round(float(cancel_rate), 2), 'booking_count_today': booking_set.count(), 'activity_count_today': activity_set.count(), 'activities_today': activity_set, 'bookings_today': booking_set, 'booking_hour_plot': plot, })
步骤2:修改模板stats.html的图表引用代码
将base64字符串传入img标签的src属性即可展示图片:
<li>实时图表: <img src="data:image/png;base64,{{ booking_hour_plot }}" alt="预订时段统计图"></li>
注意事项
- 如果图表需要展示中文,需额外配置matplotlib的中文字体,避免中文显示为方框
- 若图表生成频率低、数量多,也可选择将图片存储到Django的media目录,将文件路径传递给模板展示,这种方案需要额外处理文件命名、过期清理逻辑
内容的提问来源于stack exchange,提问作者Jingyu Xiang
相关产品推荐
相关产品推荐

