Reputation: 4161
In a Django view, I can generate a dynamic image (a graph in PNG format), and it creates a response that is an image of my graph. I can get it to display in the browser, but there is no web page with it - it's just the image. Now I'd like to embed this image in an HTML template and render it. How can I do that? (This is my first Django project.)
import matplotlib.pyplot as plt
import numpy as np
import io
# Initialize the matplotlib figure
f, ax = plt.subplots(figsize=(6, 15))
width = my_data['bar_length']
data_names = my_data['ObjectNames']
y_pos = np.arange(len(data_names))
norm = plt.Normalize(my_data['bar_length'].min(), my_data['bar_length'].max())
cmap = plt.get_cmap("RdYlGn")
# Create horizontal bars
plt.barh(y_pos, width, color=cmap(norm(my_data['bar_length'].values)))
# Create names on the y-axis
plt.yticks(y_pos, data_names)
FigureCanvasAgg(f)
buf = io.BytesIO()
plt.savefig(buf, format='png')
plt.close(f)
response = HttpResponse(buf.getvalue(), content_type='image/png')
# This works, but it generates just an image (no web page)
return response
# This ends up displaying the bytes of the image as text
#return render(request, 'my_app/graph.html', {'graph1': buf.getvalue()})
# This is what is in the graph.html template
# <div class="graph1">
# {{graph1 | safe}}
# </div>
Upvotes: 4
Views: 505
Reputation: 4161
Solved: I can pass the image as a base64 encoded string
buf = io.BytesIO()
plt.savefig(buf, format='png')
plt.close(f)
img_b64 = base64.b64encode(buf.getvalue()).decode()
return render(request, 'my_app/graph.html', {'graph1b64': img_b64})
# in graph.html
<div class="graph1">
<img src="data:image/png;base64, {{ graph1b64 }}" alt="graph1" />
</div>
Upvotes: 2