Use Pandas plot() in Django dinamically chart request

2,682 views
Skip to first unread message

j2f...@gmail.com

unread,
Apr 20, 2013, 10:07:13 AM4/20/13
to pyd...@googlegroups.com
Hi,
I use Django for web applications, and Pandas for data management. I try to use Pandas plot for introduce graph in mi web pages.
When I use de code below in the browser directly, it's work fine, but when I put into de html, this only work with one chart. If only put one graph, also work fine, but with two or more charts in the same html archive, the result is aleatory.
I think that the problem is that Pandas plot() use plt(pyplot) that remains between request. 
In this case, the browser-server request asynchronous make two or mor request at the same time, with extranger results. 
I think too that the solution is in the use of independ figure in each request like (fig = Figure() and not fig=plt.figure(...)) but seems that Pandas plot use plt internally.

So, somebody know how to use Pandas plot() in Django, with multiples request?. 

Best Regards

----------------------------------------------------------------------------------------------------------------------------------------------------------

The code is (only the important):

In urls.py:

urlpatterns = patterns('',
url(r'^$', 'myapp.views.home', name='home'),
url(r'^charts/$', 'Agricolae.views.Pandas_Graph'),   #/1/ indica chars tipo evolución
 
In myapp.views:

import matplotlib.pyplt as plt
import pandas as pd
import numpy as np

def home(request):
return render_to_response("index.html",locals())
def Pandas_Graph(request):
#create de figure
fig=plt.figure(figsize=(6, 4.5), dpi=80,facecolor='w', edgecolor='w')
ax=fig.add_subplot(111)
#create de Dataframe and plot it
df=pd.DataFrame({'y':np.random.randn(10),'z':np.random.randn(10)},
                                 index=pd.period_range('1-2000',periods=10))
df.plot()
plt.legend(loc='best')

#pass the figure to dinamical-like-png 
canvas=FigureCanvas(fig)
response=HttpResponse(content_type='image/png')
canvas.print_png(response)

return response
In index.html:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<head>
<title>myapp</title>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
</head>
<body>

<h3>Two graph are the same, with independece of call with http://localhost:8000<h3>
<br>
The first graph<br>
<img src="/charts/">
<br>

The second graph<br>

</body>
</html>

Miki Tebeka

unread,
Apr 20, 2013, 10:45:12 AM4/20/13
to pyd...@googlegroups.com

I use Django for web applications, and Pandas for data management. I try to use Pandas plot for introduce graph in mi web pages.
I don't know about FIgureCanvas, but you can serve the image data directly in the <img> HTML element, something
like   <img src="data:image/png;base64,{}" />

You can write the figure to a StringIO, the encode the results with base64 and serve it.
For example (with flask), see https://gist.github.com/tebeka/5426211.

 HTH
--
Miki

j2f...@gmail.com

unread,
Apr 20, 2013, 2:56:48 PM4/20/13
to pyd...@googlegroups.com
Thanks Miki. 

With one chart all is fine. I think that problem is the asincronous request. The problem is present when the html-file request more than one plot. Has you try this with a code like...:

<html>
    <body>

        <img src="data:image/png;base64,{}" />
        <img src="data:image/png;base64,{}" />
        <img src="data:image/png;base64,{}" />
    </body>
</html>

I don´t know flask but I think that the problem will be the same, because we haven´t control about the order of the request is server. or Yes?. Seems, that the Server try to server all contain of the html file in the same moment, or aleatoy moment. This, in many traits, twice only represent the first graph, other twice the second one, and others the charts combined with all lines in the same plot. Unpredictable behavior. Seems that this depend of the status of the plt object in the moment of the request. This is so because this object (plt) is maintained across requests, preserving their features. Only one plt object for all requests. What would we want is that plt was created and destroy in each of the requests. This is, that Pandas works directly on a Figure () and not on pyplot. I think so.

regards

Juan Na

unread,
Apr 20, 2013, 4:19:34 PM4/20/13
to pyd...@googlegroups.com
sorry, FigureCanvas is:

from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas

Miki Tebeka

unread,
Apr 21, 2013, 11:27:45 AM4/21/13
to pyd...@googlegroups.com

With one chart all is fine. I think that problem is the asincronous request. The problem is present when the html-file request more than one plot. Has you try this with a code like...:
 
Seems that this depend of the status of the plt object in the moment of the request. This is so because this object (plt) is maintained across requests, preserving their features. Only one plt object for all requests. What would we want is that plt was created and destroy in each of the requests. This is, that Pandas works directly on a Figure () and not on pyplot. I think so.
plt is a module, and there's only one of it at any time. If you look at the gist I posted, I create a new figure on every request and serve the data from it. This ensures I don't have any data corruption between two requests. 
In general try to make your web server as stateless as possible and think super carefully about locking when you can't (which is a very rare case).

John Na

unread,
Apr 21, 2013, 4:49:40 PM4/21/13
to pyd...@googlegroups.com
Thank Mike. Realy the code that I show don´t work. And as you say, this code create a new plt.figure in one independ process, but... don´t work. Some time ago I work with matplotlib and Django, and this is fine when used fig = Figure () ... ax.plot () ... as described in, for example, http://www.scipy.org/Cookbook/Matplotlib/Django. The only difference I see with this code is the assignment fig = plt.figure () ..., maybe the problem is there. I do not know

And I'm sorry because I'm very pleased with Pandas, and it graphics capabilities. Perhaps, I think now, the problem can be in the server of Django (of development). I'll try with Apache or Nginx and then comment here.

PD: Sorry for my English. I'm from Spain and I try this without google translator or similar. Is muy exercise

Juan

Miki Tebeka

unread,
Apr 22, 2013, 6:30:25 PM4/22/13
to pyd...@googlegroups.com
> The only difference I see with this code is the assignment fig = plt.figure () ..., maybe the problem is there. I do not know
I *think* it is. Since this mean you generate a fresh image every requests and not using an old one.

PD: Sorry for my English. I'm from Spain and I try this without google translator or similar. Is muy exercise
No worries, I'm from Israel. We learn English as we go. 
Reply all
Reply to author
Forward
0 new messages