From charlesreid1

(Created page with "=Types of Plots= ==Histogram== <source lang="python"> from matplotlib import rcParams from pylab import * # construct the distribution with a given mean and deviation: # -----...")
 
No edit summary
 
(9 intermediate revisions by the same user not shown)
Line 1: Line 1:
=Types of Plots=
=Using Matplotlib in Web Apps=


==Histogram==
I wanted to write a Python web app that would call Matplotlib to visualize some data on the back end, and serve it up to a browser window on the front end.
 
Initially I saw [webplotlib https://pypi.python.org/pypi/webplotlib/0.1], which looked promising, but wrapped all of matplotlib into two dinky kinds of plots: time series, and bar charts. I needed something that, like webplotlib, could communicate a figure to a browser, but something that, unlike webplotlib, still kept the full functionality of matplotlib.
 
The fix was easy. The core functionality of webplotlib is passing a figure as a string to the browser; this is about 4 lines. The rest is entirely case-dependent.
 
Let's walk through how to do this.
 
==Step 1: Create Your Figure==
 
Some quick code to make a dummy figure:
 
<source lang="python">
def make_dummy_figure():
    import matplotlib.pylab as plt
    from numpy.random import *
 
    fig = plt.figure()
    ax1 = fig.add_subplot(1,2,1)
    ax2 = fig.add_subplot(1,2,2)
 
    x = range(10)
    y1 = rand(10,)
    y2 = 1000*rand(10,)
 
    ax1.plot(x,y1,'b-')
    ax2.plot(x,y2,'r-')
 
    ax1.set_xlabel('Number of Llamas')
    ax1.set_ylabel('People killed')
 
    ax2.set_xlabel('Number of Tigers')
    ax2.set_ylabel('People killed')
 
</source>
 
[[Image:DummyPlot.png]]
 
==Step 2: Make a Sendable Figure==
 
To send a figure to our web application, we need to make the figure sendable. We modify the script to return a FigureCanvas handle to our figure,


<source lang="python">
<source lang="python">
from matplotlib import rcParams
import matplotlib.pylab as plt
from pylab import *
from numpy.random import *


# construct the distribution with a given mean and deviation:
matplotlib.use('Agg')
# -----------------------------------------------------------
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas


# mu = mean
def make_dummy_figure():
# sigma = standard deviation
# randn(10000) creates an array of size 10,000 x 1 that contains random numbers
mu, sigma = 0, 0.5
x = mu + sigma*randn(10000)


# plot the histogram of the data:
    fig = plt.figure()
# --------------------------
    ax1 = fig.add_subplot(1,2,1)
    ax2 = fig.add_subplot(1,2,2)


figure(1)
    x = range(10)
    y1 = rand(10,)
    y2 = 1000*rand(10,)


# this will plot the data with the y-axis as the total number of samples (i.e. 350+)
    ax1.plot(x,y1,'b-')
#n, bins, patches = hist(x, 100,)
    ax2.plot(x,y2,'r-')
# this will plot the histogram with a normalized y-axis
 
n, bins, patches = hist(x, 100, normed=1)
    ax1.set_xlabel('Number of Llamas')
    ax1.set_ylabel('People killed')
 
    ax2.set_xlabel('Number of Tigers')
    ax2.set_ylabel('People killed')
 
    return FigureCanvas(fig)
</source>
</source>


==Step 3: Should've Put a String on it==
Let's define a function that will turn that figure into a StringIO object:
<pre>
def stringify_dummy_figure():
    figcanvas = make_dummy_figure()
    img_data_str = StringIO()
    figcanvas.print_png(img_data_str)
    img_data_str.seek(0)  # After writing, rewind data for further use.
    return img_data_str.read()
</pre>


==Step 4: Make an HTTP Response==


The last step is to pass that string to an HTTP response


<pre>
from django.http import HttpResponse, HttpResponseRedirect


img_str = stringify_dummy_figure()
response = HttpResponse(img_str, mimetype='image/png')
</pre>


and that can be embedded into your web app, wherever it lays out the logic for parsing URLs and crafting HTTP responses.








[[Category:Computers]]
{{ScientificComputingFlag}}
[[Category:Programs]]
{{PythonFlag}}

Latest revision as of 07:18, 16 April 2017

Using Matplotlib in Web Apps

I wanted to write a Python web app that would call Matplotlib to visualize some data on the back end, and serve it up to a browser window on the front end.

Initially I saw [webplotlib https://pypi.python.org/pypi/webplotlib/0.1], which looked promising, but wrapped all of matplotlib into two dinky kinds of plots: time series, and bar charts. I needed something that, like webplotlib, could communicate a figure to a browser, but something that, unlike webplotlib, still kept the full functionality of matplotlib.

The fix was easy. The core functionality of webplotlib is passing a figure as a string to the browser; this is about 4 lines. The rest is entirely case-dependent.

Let's walk through how to do this.

Step 1: Create Your Figure

Some quick code to make a dummy figure:

def make_dummy_figure():
    import matplotlib.pylab as plt
    from numpy.random import *

    fig = plt.figure()
    ax1 = fig.add_subplot(1,2,1)
    ax2 = fig.add_subplot(1,2,2)

    x = range(10)
    y1 = rand(10,)
    y2 = 1000*rand(10,)

    ax1.plot(x,y1,'b-')
    ax2.plot(x,y2,'r-')

    ax1.set_xlabel('Number of Llamas')
    ax1.set_ylabel('People killed')

    ax2.set_xlabel('Number of Tigers')
    ax2.set_ylabel('People killed')

DummyPlot.png

Step 2: Make a Sendable Figure

To send a figure to our web application, we need to make the figure sendable. We modify the script to return a FigureCanvas handle to our figure,

import matplotlib.pylab as plt
from numpy.random import *

matplotlib.use('Agg')
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas

def make_dummy_figure():

    fig = plt.figure()
    ax1 = fig.add_subplot(1,2,1)
    ax2 = fig.add_subplot(1,2,2)

    x = range(10)
    y1 = rand(10,)
    y2 = 1000*rand(10,)

    ax1.plot(x,y1,'b-')
    ax2.plot(x,y2,'r-')

    ax1.set_xlabel('Number of Llamas')
    ax1.set_ylabel('People killed')

    ax2.set_xlabel('Number of Tigers')
    ax2.set_ylabel('People killed')

    return FigureCanvas(fig)

Step 3: Should've Put a String on it

Let's define a function that will turn that figure into a StringIO object:

def stringify_dummy_figure():
    figcanvas = make_dummy_figure()
    img_data_str = StringIO()
    figcanvas.print_png(img_data_str)
    img_data_str.seek(0)  # After writing, rewind data for further use.
    return img_data_str.read()

Step 4: Make an HTTP Response

The last step is to pass that string to an HTTP response

from django.http import HttpResponse, HttpResponseRedirect

img_str = stringify_dummy_figure()
response = HttpResponse(img_str, mimetype='image/png')

and that can be embedded into your web app, wherever it lays out the logic for parsing URLs and crafting HTTP responses.