Reputation: 43
I have created a plot in a view and saved the plot as a png inside the templates folder. But when I try to display this saved image using an <img>
tag in a template html file, the image is not displayed.
Here is an image of my folder structure:
Folder Structure
This is how I save my plot inside a view:
def result(request):
if request.POST and request.FILES:
mycsv=pd.read_csv(request.FILES['csv_file'])
c=mycsv.X
#We divide by the class height(basically) so that Xi+1-Xi=1
x = [d / 5 for d in c]
n=len(x)
b=mycsv.Y
divi=np.sum(b)
f = [e / divi for e in b]
#Thus sum(f)=1, makes calculation of mean simpler
#PLOTTING BEGINS
fig = plt.figure()
ax = plt.subplot(111)
ax.plot(x, f)
plt.title('Pearson Type 1 ')
ax.legend()
#plt.show()
fig.savefig('polls/templates/polls/plot.png')
context = {'n':n,}
return render(request, 'polls/result.html', context)
else:
return HttpResponse("Form Not Submitted")
My result.html file where I try to get the image is:
<h1>Graph with {{n}} points</h1>
<img src='./plot.png' />
I'm running this on my localhost, is there a problem with permissions?
I've just started learning django and wanted to test this thing. Thank you for your help!
Upvotes: 3
Views: 3463
Reputation: 11
I experienced such issues while generating a dynamic graph, I simply used this format.
If the image is saved with a specific filename statically and it's not being regenerated dynamically each time, then rendering it using the static tag wouldn't work as expected. In this case, you should directly use the URL path to the image without the static tag.
Here's how you can update the tag in your HTML template:
I was using this format before:
<img src="{% static 'images/female_graph_'|add:request.user.id|stringformat:".png" %}" alt="Female Spouse Graph">
The correct way of rendering dynamic images stored in a static file:
<img src="/static/images/female_graph_{{ request.user.id }}.png" alt=" Female Spouse Graph">
Ensure you used the HTML tag correctly <> before the img src. open and close the image tag.
Replace /static/ with the appropriate URL path to your static files if needed. This way, the browser will directly request the image from the correct URL without involving the static tag, and it should render properly.
Upvotes: 1
Reputation: 21
Or simply convert the image to string by
with open(original_image_path, "rb") as img_file:
base64_img = base64.b64encode(img_file.read()).decode('utf-8')
mimetype = mimetypes.guess_type(original_image_path)[0]
once done render this variable on HTML as
<img src="data:{{ mimetype }};base64,{{ base64_img }}"/>
It will handle both jpeg and png both.
Upvotes: 1
Reputation: 8506
There are many things wrong about your approach but I'll try to give you some advice on how to proceed, although you may want to reconsider it.
First of all, saving your file to the templates directory won't make it available to your template. The templates directory is a special configuration that allows you to use Django's template loader, it doesn't load static files like your image.
You could save your image to static files and use the {% static %}
template tag to recover it, but, again, it would be the wrong approach, as your image is not static content, it's created dynamically.
As you have no use for the data in the image after it's created, my recommendation would be to store the image in a temporary file using TempFile, or (if it's light enough) in memory using StringIO and then load those bytes in the context as base64
from StringIO import StringIO
import base64
img_in_memory = StringIO()
fig.savefig(img_in_memory, format="png") #dunno if your library can do that.
context['image'] = base64.b64encode(img_in_memory.getvalue())
Then, in your template you'd do something like:
<img src="data:image/png;base64,{{image}}" />
Upvotes: 7