I'm trying to build a web app which shows the user the variation of his weight over time. Therefore I'm trying to plot a line graph. I want to make use of matplotlib or a similar library inside my views file to plot the graph.
This answer explains how the graph can be plotted through Django views.
My code in views.py file looks like this:(no need to read in detail, it's working fine)
from django.shortcuts import render, HttpResponseRedirect, HttpResponse
from .forms import DiabetesForm
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure
import matplotlib as plt
from matplotlib.dates import DateFormatter
import datetime
import random
import io
def mplimage(request):
f = Figure()
ax = f.add_subplot(111)
x = []
y = []
now = datetime.datetime.now()
delta = datetime.timedelta(days=1)
for i in range(10):
x.append(now)
now += delta
y.append(random.randint(0, 1000))
ax.plot_date(x, y, '-')
ax.xaxis.set_major_formatter(DateFormatter('%Y-%m-%d'))
f.autofmt_xdate()
buf = io.BytesIO()
canvas = FigureCanvas(f)
canvas.print_png(buf)
response=HttpResponse(buf.getvalue(),content_type='image/png')
# if required clear the figure for reuse
f.clear()
# I recommend to add Content-Length for Django
response['Content-Length'] = str(len(response.content))
#
return response
And the code in urls.py is:
from django.urls import path, include
from . import views
urlpatterns = [
path('', views.mplimage, name='home'),
]
However, this code shows only the plotted image( that was generated in views.py file ) in the HTML page.
What I want:
I want to pass the generated image and the template name together in the render function so that apart from the image I can other information/content written as well.
In other words, I want to make use of the passed image in my HTML page which can hold other content too.
Any other method through which I can do the job will also be highly appreciated.
Edit: I don't know much of javascript, so please don't give answers related to javascript unless there's no other method.
Edit2:Here the updated and working code as suggested by @Mikhail (second method):
from django.shortcuts import render, HttpResponseRedirect, HttpResponse
from .forms import DiabetesForm
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure
import matplotlib as plt
from matplotlib.dates import DateFormatter
import datetime
import random
import io
import base64
def mplimage(request):
f = Figure()
ax = f.add_subplot(111)
x = []
y = []
now = datetime.datetime.now()
delta = datetime.timedelta(days=1)
for i in range(10):
x.append(now)
now += delta
y.append(random.randint(0, 1000))
ax.plot_date(x, y, '-')
ax.xaxis.set_major_formatter(DateFormatter('%Y-%m-%d'))
f.autofmt_xdate()
buf = io.BytesIO()
canvas = FigureCanvas(f)
canvas.print_png(buf)
response=HttpResponse(buf.getvalue(),content_type='image/png')
# if required clear the figure for reuse
img_str = base64.b64encode(buf.getvalue())
data_url = 'data:image/jpg;base64,' + base64.b64encode(buf.getvalue()).decode()
f.clear()
# I recommend to add Content-Length for Django
#response['Content-Length'] = str(len(response.content))
#
#return response
return render(request, "display.html", {'image': data_url })
Here's the display.html file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Display</title>
</head>
<body>
<img src="{{ image }}" alt=""/>
<h1>Write whatever you want</h1>
</body>
</html>