matplotlib作为python的一个数据可视化包,一个画图包,真的非常不错。
通过下面这一段代码
import matplotlib.pyplot as plt
plt.matshow(price, cmap=plt.cm.Blues)
plt.xticks(np.arange(1, int(row)), [])
plt.yticks(np.arange(1, int(height)), [])
plt.plot(path[:, 1] - 1, path[:, 0] - 1, linewidth=8)
plt.colorbar()
我们可以创建一张图,这张图现在在内存中,我们想把这张图返回到网页上。
现在就有一个问题,我们改如何获取这张图的二进制数据呢?
解决方法1:先把它保存到本地,通过
plt.savefig()
然后读取,这确实可以。但是有个问题,如果多人同时访问网站呢?这时候,保存的文件就会被一次一次的覆盖,访问者最后看到的可能就不是自己想要的。
通过查看源码,和自己百度,最终找到了解决方案。
canvas = plt.get_current_fig_manager().canvas
canvas.draw()
buffer = io.BytesIO()
canvas.print_png(buffer)
data = buffer.getvalue()
buffer.close()
现在data就是我们想要的二进制图片数据,我们可以把它写到一个文件中看看
f=open('hh.png',mode='wb')
f.write(data)
f.close()
可以打开看看,确实是我们想要的图片。
现在我们的问题就是如何把二进制图片返回给页面
return HttpResponse(data, content_type="Image/png")
这样打开这个对应的url,就可以看到一张图片。
把我这个整个函数粘到这里
def plot(request):
import numpy as np
import pandas as pd
import io
import matplotlib.pyplot as plt
price=request.session['price']
height=request.session['height']
row=request.session['row']
ss=request.session['res']
price = np.array(price)
price=price.reshape(int(row),int(height))
path = pd.Series(ss.split('\n')[1:-1]).apply(lambda x: x.split(' ')).values
path = np.array(list(path)).astype('int')
#上面的代码是我获取数据和对数据修改的代码,和此文章重点无关
plt.matshow(price, cmap=plt.cm.Blues)
plt.xticks(np.arange(1, int(row)), [])
plt.yticks(np.arange(1, int(height)), [])
plt.plot(path[:, 1] - 1, path[:, 0] - 1, linewidth=8)
plt.colorbar()
# plt.savefig()
canvas = plt.get_current_fig_manager().canvas
canvas.draw()
buffer = io.BytesIO()
canvas.print_png(buffer)
data = buffer.getvalue()
buffer.close()
return HttpResponse(data, content_type="Image/png")
到这里其实就可以结束了,但是这样画出来的图就是固定的,不是我们想要的
所以我们需要获取画图的数据。画图的数据从哪里获取?
我这里采用了session的方法。
<form action="/result/" method="post">
{% csrf_token %}
<input type="hidden" name="row" value="{{row}}"/>
<input type="hidden" name="height" value="{{height}}"/>
{% for i in rows %}
{% for j in heights %}
<input type="text" name="{{i}},{{j}}"/>
{%endfor%}
<br>
{%endfor%}
<br>
<input type="submit">
form>
def result(request):
height=request.POST.get('height','0')
row=request.POST.get('row','0')
paramer=str(row)+' '+str(height)+' '
price=[]
for i in range(int(row)):
for j in range(int(height)):
paramer=paramer+request.POST.get(str(i)+','+str(j),'0,0')+" "
price.append(int(request.POST.get(str(i)+','+str(j),'0')))
res=get_result(paramer)
request.session['price'] = price
request.session['height'] = height
request.session['row'] = row
request.session['res'] = res
# return HttpResponse(graphic, content_type="Image/png")
return render(request,'algorithm/result.html',{'res':res.split('\n')[0]})
def get_result(paramer):
import os
hh=os.popen('4.exe '+paramer)
ss=hh.read()
hh.close()
return ss
就是这样,也可以直接form提交到plot中,但不是我想要的效果
注意:使用session,必须运行
python manage.py migrate
不然会出错。