【发布时间】: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')
]
html
<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
我得到了答案,以下是修改后的代码
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 函数,这可能会涵盖您指出的内容。尽管如此,这仍然没有解决我的麻烦。我该怎么办......我真的很茫然
-
现在会发生什么?两次相同的图表?
标签: django matplotlib graph save bytesio