Ooops, forgot the attachment.
Alan

"""
Adapts John Hunter's example of how to use a path patch to draw a bunch of
rectangles for an animated histogram
"""
import Tkinter as tk
import numpy as np
import matplotlib as mpl
mpl.use('TkAgg')

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, 
NavigationToolbar2TkAgg
from matplotlib.figure import Figure 

class Histogram(FigureCanvasTkAgg):
        """Provides a simple normed histogram.
        Here `datafunc` returns a sequence (e.g., a list or array)
        containing a single iteration's data.
        :thanks: John Hunter showed in detail how to do this with a PathPatch
                (Aug 8, 2009, Matplotlib users mailing list)
        """
        def __init__(self, datafunc, bins, master=None, title='', world=None, 
**kwargs):
                self._datafunc = datafunc
                self._tops = None
                self._edges = None
                self._rectverts = None
                self._xlim = None
                self._bins = bins
                self._title = title
                self._world = world
                self._background = None
                self._kwargs = kwargs
                self._fig = mpl.figure.Figure(figsize=(5,2.5), dpi=100)
                self._ax = self._fig.add_subplot(111, title=title)
                #grid the widget to master
                FigureCanvasTkAgg.__init__(self, self._fig, master=master)
                self.get_tk_widget().grid(row=0,column=1)
        def setup(self):
                self._ax.set_title(self._title, fontsize='x-small')
                # create the initial histogram
                self.update_data()
                self.create_rectangles_as_pathpatch()
        def update(self):
                """Return None. Update the histogram."""
                # update the data (-> _tops)
                self.update_data()
                #update the vertices
                newtops = self._tops
                self._rectverts[1::5,1] = newtops
                self._rectverts[2::5,1] = newtops
                self.show()  #crucial!
        def update_data(self):
                """Return sequence, the new data from `_datafunc`.
                """
                data = self._datafunc()
                tops, edges = np.histogram(data, bins=self._bins, normed=True, 
**self._kwargs)
                self._tops, self._edges = tops, edges
        def create_rectangles_as_pathpatch(self):
                global rectverts
                """
                The tricky part: we construct the rectangles as a `mpl.path`
                http://matplotlib.sourceforge.net/api/path_api.html
                and then add a mpl.patches.PathPatch to the axes.
                (Thanks to John Hunter, who posted this solution!!)
                """
                ax = self._ax
                tops, edges = self._tops, self._edges
                # first create the vertices and associated rectvertcodes
                self._rectverts = rectverts = self.create_rectverts(tops, edges)
                numrects = len(tops) #keep it this way
                self._rectvertcodes = rectvertcodes = 
self.create_rectvertcodes(numrects)
                barpath = mpl.path.Path(rectverts, rectvertcodes)
                patch = mpl.patches.PathPatch(barpath, facecolor='green', 
edgecolor='yellow', alpha=0.5)
                self._patch = ax.add_patch(patch)
                self._xlim = xlim = (edges[0],edges[-1])
                ax.set_xlim(xlim)
                ax.set_ylim(0,1)
        def create_rectverts(self, tops, edges):
                """Return array, the vertices for rectangles with
                bottoms 0, tops `tops`, and edges `edges`.
                Please refer to `create_rectvertcodes`:
                although the vert for the closepoly is ignored,
                we still need it to align with the rectvertcodes.
                """
                numrects = len(tops) #keep it this way
                nverts = numrects*(1+3+1)
                #we will replace the tops; bottoms remain 0
                rectverts = np.zeros((nverts, 2))
                # get the corners of the rectangles for the histogram
                left_edges = np.array(edges[:-1])
                right_edges = np.array(edges[1:])
                rectverts[0::5,0] = left_edges
                rectverts[1::5,0] = left_edges
                rectverts[1::5,1] = tops
                rectverts[2::5,0] = right_edges
                rectverts[2::5,1] = tops
                rectverts[3::5,0] = right_edges
                return rectverts
        def create_rectvertcodes(self, numrects):
                """Return 1d array, the codes for rectangle creation.
                (Each rectangle is one moveto, three lineto, one closepoly.)
                """
                numverts = numrects*(1+3+1)
                rectvertcodes = np.ones(numverts, int) * mpl.path.Path.LINETO
                rectvertcodes[0::5] = mpl.path.Path.MOVETO
                rectvertcodes[4::5] = mpl.path.Path.CLOSEPOLY
                return rectvertcodes
        cnt = 0
        def run(self):
                while self.cnt < 100:
                        self.cnt += 1
                        self.update()


#example: trivial data function
def get_data():
        raw_data = np.random.randn(1000)
        return raw_data.clip(-2,2)

mybins = np.linspace(-2, 2, 50, True)
root = tk.Tk()
hist = Histogram(get_data, mybins, master=root, title='histogram')
hist.setup()
btn = tk.Button(master=root, text='Run', command=hist.run)
btn.grid(row=0, column=0)
root.mainloop()

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with 
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users

Reply via email to