Django:如何将每个图形放在页面上而不保存它
Posted
技术标签:
【中文标题】Django:如何将每个图形放在页面上而不保存它【英文标题】:Django: How to put each graphs on a page without saving it 【发布时间】:2020-03-06 09:59:47 【问题描述】:我正在努力将使用 Matplotlib 创建的几个图表放在一个页面上,并将其保存在内存中。虽然单个图成功了,但还有一个图失败了。例如,当我尝试在网页中嵌入两个 matplotlib 图(graph1 和 graph2)时,它会显示一个组合图。此外,指定的颜色也不起作用。为什么?我想知道的是如何在没有集成的情况下显示每个图表。
以下是我的代码 Views.py Matplotlib 图被转换为二进制数据并保存在内存中 每个图都连接到url参数
def graph():
#create graph and save it on memory
buff=io.BytesIO()
plt.savefig(buff, format='png')
bute_file=buff.getvalue()
buff.close
return bute_file
def test_graph(request,para):
if para==1: #graph1
accounts=[6,2,3,6]
label=['A','B','C','D']
col=['darkred','red','orange','gold']
plt.pie(accounts,labels=label,colors=col)
chart=graph()
plt.cla
response=HttpResponse(chart, content_type='image/png')
return response
elif para==2: #graph2
accounts=[3,6,9]
label=['E','F','G']
col=['blue','cyan','darkblue']
plt.pie(accounts,labels=label,colors=col)
chart=graph()
plt.cla
response=HttpResponse(chart, content_type='image/png')
return response
else: #graph3
accounts=[5,1,2]
label=['X','Y','Z']
col=['green','limegreen','yellowgreen']
plt.pie(accounts,labels=label)
chart=graph()
plt.cla
response=HttpResponse(chart, content_type='image/png')
return response
url.py
urlpatterns = [
path('test_view/',views.test_view, name='test_view'),
path('test/<int:para>',views.test_graph,name='test_graph')
]
<div>
<img src="% url 'mysite:test_graph' 1 %">
</div>
<div>
<img src="% url 'mysite:test_graph' 2 %">
</div>
这是显示的页面
将 test_graph() 中的 para 更改为 url 参数上不存在的 3,4,网页显示了异常的 graph(graph3),似乎运行良好
请给我一些建议或解决方案
PS。以下消息是否涉及? 警告:NSWindow 拖动区域应该只在主线程上无效!这样以后会抛出异常
编辑 我可以通过添加“matplotlib.use('Agg')”来解决 WARING 消息
修改 test_graph 函数 IAW ger.s.brett 建议并消除图函数
def test_graph(request,para):
plt.clf()
if para==1: #graph1
..........
elif para==2: #graph2
..........
else: #graph3
.........
plt.pie(accounts,labels=label,colors=col)
buff=io.BytesIO()
plt.savefig(buff, format='png')
chart=buff.getvalue()
buff.close()
response=HttpResponse(chart, content_type='image/png')
return response
编辑 2 添加输出图,每次访问网页
我得到了答案,以下是修改后的代码
view.py
class TestView(TemplateView):
template_name='mysite/test.html'
def test_graph(self,accounts,label,col):
plt.pie(accounts,labels=label,colors=col)
buff=io.BytesIO()
plt.savefig(buff, format='png')
buff.seek(0)
chart=b64encode(buff.getvalue()).decode('utf-8').replace("","")
plt.close()
buff.close()
return chart
def get_context_data(self,**kwargs):
context=super().get_context_data(**kwargs)
graph_1=self.test_graph([3,6,9],['E','F','G'],['blue','cyan','darkblue'])
graph_2=self.test_graph([6,2,3,6],['A','B','C','D'],['darkred','red','orange','gold'])
context['graph_1']=graph_1
context['graph_2']=graph_2
return context
test.html
<div>
<img src="data:image/png;base64,graph_1">
</div>
<div>
<img src="data:image/png;base64,graph_2">
</div>
所以...原来如此简单
【问题讨论】:
尝试清除 test_graph 函数开头的 plt:plt.clf()。 感谢 ger.s.brett,我尝试添加 plt.clf()。但这根本解决不了我的问题。更重要的是,每个图形的图形都不一样,每次都重复访问test_graph,例如只显示一个图形,两个相同的graph2s或不显示颜色图形。那么,您有什么建议吗? 我会担心您对 plt 对象的处理。为什么不将其作为函数参数传递给图形函数? 我修改了 test_graph 函数并消除了 graph 函数,这可能会涵盖您指出的内容。尽管如此,这仍然没有解决我的麻烦。我该怎么办......我真的很茫然 现在会发生什么?两次相同的图表? 【参考方案1】:如果你想在 django 中使用 matplotlib,请使用 django-matplotlib 之类的东西。
只有在使用 python 交互时才使用 plt 对象是一个好主意。
【讨论】:
感谢您给我额外的建议。我尝试将 django_matplotblib 模块集成到我的模型中,将图表嵌入到我的网页中。但它不起作用,而图形可以显示在管理页面上。这是因为无法从模型(DjangoMatplotlibField)传递图形。另一方面,我可以找到一种替代方法,即将 HttpResponse 对象作为嵌入 html 文档的对象切换为上下文对象。我添加了修改后的代码。以上是关于Django:如何将每个图形放在页面上而不保存它的主要内容,如果未能解决你的问题,请参考以下文章
我想弹出我自己的对话框(将文件保存在服务器上而不询问目标路径位置)而不是 adobe 的另存为对话框