3

I'm currently generating an image via matplotlib using the properties of an object, and am able to create a view that displays said image in a HttpResponse. I used the following snippet to do so: http://wiki.scipy.org/Cookbook/Matplotlib/Django. I've also configured my URLs to both generate and display the image successfully when I navigate to domain.com/objectID.png

Right now I want to create a form, whose inputs will be used to generate an image from matplotlib. Then I want to display this generated image back to the user on the same page of the form.

How should I feed the inputs of the form to my matplotlib image generator, and then display the resulting image back to the user?

Thank you very much for your help.

Best regards

EDIT 1: I was looking for a solution, and I believe I would display the image as follows in my template. Not sure how to feed the variable 'img' though:

{% if img %} <img border="0" alt="My Generated Image" src="{{ img }}" /> {% endif %}
xyres
  • 20,487
  • 3
  • 56
  • 85

3 Answers3

3

Let's say you want to generate a simple graph/image after a user enters the x and y co-ordinates.

Requirements:

  1. jQuery
  2. jQuery Form Plugin

HTML :

<form method="POST" action="/generate-image/" id="GenImgForm">
    <input type="text" name="x-coordinate" />
    <input type="text" name="y-coordinate" />
</form>

<!-- Make an empty div where the returned image will be shown -->
<div id="ShowImage"></div>

<script type="text/javascript" src="/static/path/to/jquery.js"></script>
<script type="text/javascript" src="/static/path/to/jquery.form.js"></script>
<script type="text/javascript">
    $(document).ready(function() {
        var options = { 
            target: '#ShowImage',
        };        
        $("#GenImgForm").ajaxForm(options);
            return false;
        });
</script>

views.py :

Now, in your views, you will have to follow this approach:

  1. Generate an image using matplotlib.
  2. Save it as a StringIO object.
  3. Encode the StringIO object to base64.
  4. Send it back to the client.

Take a look at this question.

import cStringIO # use import io in Python 3x
# import base64 Use this in Python 3x

def generate_image(request):
    if request.method == 'POST':
        x_coord = request.POST['x-coordinate']
        y_coord = request.POST['y-coordinate']

        # generate a matplotlib image, (I don't know how to do that)

        sio = cStringIO.StringIO() # use io.StringIO() in Python 3x
        pyplot.savefig(sio, format="PNG")

        encoded_img = sio.getvalue().encode('Base64') # On Python 3x, use base64.b64encode(sio.getvalue())

        return HttpResponse('<img src="data:image/png;base64,%s" />' %encoded_img)
    else:
        # Do something ...
Community
  • 1
  • 1
xyres
  • 20,487
  • 3
  • 56
  • 85
  • Wonderful reply, thank you so much. If you could walk me through the JavaScript function, just so I fully understand what is going on, I would very much appreciate it. – Christian Yenko Mar 30 '14 at 18:50
  • All the JS code is basically to access the API of jQuery and jQuery Form Plugin, actually. So, you don't have to really worry about it because all the code to handle your forms has already been written in that plugin. You just have to write some lines to access their APIs, and that is what I did. Read this documentation: http://malsup.com/jquery/form/#getting-started – xyres Mar 31 '14 at 05:14
  • 2
    Accepted the answer, after getting it to work. Thank you very much for your help! As a side note for future readers, I believe form ID should be fixed from '#GenImgForm' to 'GenImgForm'. – Christian Yenko Mar 31 '14 at 06:10
  • Thank you. I'm glad it helped. And thanks for pointing out that error in form's `id`. I've fixed it now. – xyres Mar 31 '14 at 07:04
1

My answer is almost same as the accepted answer with few working changes.

views.py :

from matplotlib import pyplot as plt
import io
plt.plot([1, 2, 3, 4])
plt.ylabel('some numbers')
sio = io.BytesIO()
plt.savefig(sio, format="png")
encoded_img = base64.b64encode(sio.getvalue())
return HttpResponse(encoded_img)

html:

<img id="plt" src=""></img>

jQuery ajax code:

  $.ajax(
   {
     headers: {"X-CSRFToken":token},
     type: "GET",
     url: "ajax/show_hcPlot",
     success: function(response){

       $("#plt").attr('src',"data:image/png;base64, " + response);
     }
   }
  )
aashu
  • 23
  • 4
0

You would need to make an AJAX request to the server to serve some url via javascript (possibly with the aid of some library like jQuery). The request would pass on the data in the form and return a link to the appropriate image.

ubadub
  • 3,571
  • 21
  • 32