From: Thomas B. <tho...@ya...> - 2004-08-17 09:11:56
|
Hello, I am fairly new to matplotlib in particular and using gui's in general and don't have much experience yet with threading. From a python command prompt, I want to be able to use python to create and work with data sets, while simultaneously be able to chart the data with matplotlib. Since I would like to display more than one matplotlib chart at a time, I presume this involves working with threads. Furthermore, I would like to also display the data sets in a grid-like table, and since I want to see more than one such grid-like table at a time (and of course see grid-like tables and matplotlib charts at the same time too), I think this will also involve threading. I am currently pretty comfortable using matplotlib, though I don't yet know how to plot a chart and get the python cursor back to do more work and interact with the chart dynamically. I know wxpython has a grid-like table for displaying data called wx.grid. I was hoping to be able to use matplotlib in a threaded manner and also use these wx.grid widgets to display data in a threaded manner from the same python session. How complicated is it to accomplish this kind of functionality? Since the interactive2.py threading example uses pygtk, is pygtk the best way to create multiple, threaded plots from a python prompt and interact with them while also doing data manipulation at the python prompt? If pygtk is the best/easiest way to create threaded matplotlib plots, is it possible/desirable to utilize threaded wx.grids in the same session, or should I stick with whatever grid-like table is provided by pygtk in order for the grids to play nice with the charts (ie, keep all threaded gui objects to be pygtk widgets)? Is it not possible to use python's thread or queue module to do most of the work here, instead of utilizing pygtk threads or wxpython threads? Why cant I just create any new gui object (whether a matplotlib chart or some kind of grid-like table of data) in a new python thread? Thanks vm for your help. Tom |
From: John H. <jdh...@ac...> - 2004-08-17 17:59:52
|
>>>>> "Thomas" == Thomas Barket <tho...@ya...> writes: Thomas> Hello, I am fairly new to matplotlib in particular and Thomas> using gui's in general and don't have much experience yet Thomas> with threading. From a python command prompt, I want to Thomas> be able to use python to create and work with data sets, Thomas> while simultaneously be able to chart the data with Thomas> matplotlib. Since I would like to display more than one Thomas> matplotlib chart at a time, I presume this involves Thomas> working with threads. Furthermore, I would like to also Thomas> display the data sets in a grid-like table, and since I Thomas> want to see more than one such grid-like table at a time Thomas> (and of course see grid-like tables and matplotlib charts Thomas> at the same time too), I think this will also involve Thomas> threading. Have you had a chance to read http://matplotlib.sourceforge.net/interactive.html? This gives a little background on using matplotlib interactively. As stated on that page, the best approach with the current matplotlib (0.61) is to set backend : TkAgg interactive : True in your matplotlibrc file (http://matplotlib.sourceforge.net/faq.html#MATPLOTLIBRC). If you do this, you will not need to call show. Fernando Perez, author of ipython, is working on a much improved interactive shell for matplotlib + GTK. He plans eventually to support all the backends, but right now is focusing on GTK (tkagg already works with ipython). You will need CVS ipython and CVS matplotlib to try this out, but it is very nice. See his earlier post http://sourceforge.net/mailarchive/forum.php?thread_id=5323260&forum_id=33405 As for the grids, if I understand you correctly, the best way to do this is create multiple axes with the subplot command, eg, from matplotlib.matlab import * subplot(221) # upper left plot(range(10), 'go') subplot(222) pcolor(rand(10,10)) # upper right subplot(223) scatter(rand(12), rand(12)) # lower left subplot(224) hist(randn(10000), 100) # lower right show() Is this what you are looking for? [You can embed multiple matplotlib figure canvases into a wx grid or a gtk.Table if you want to use the GUI API, but I'm assuming you're looking for something simpler, as above]. JDH |
From: Thomas B. <tho...@ya...> - 2004-08-18 15:43:52
|
John, Many thanks for your reply. I had seen the interactive.html page before but I didn't realize I had to drop the "show()" statement in order to accomplish interactivity. Iow, I had set my matplotlibc file to have interactive be true, but when I wrote scripts, I kept on using the "show()" command. Oops. Tks for clearing that up. Btw, what does "TkAgg sets interactive mode to True when you issue the show command" mean exactly? Should it say False instead? Anyway, I kept using "show()" in my scripts, which "hid" interactivity from me. I got that now. My explanation of what I meant by displaying data in grid-like tables was not good. Pls let me try again. Your example is v informative and useful, but it doesn't get at what I had in mind. I did not mean displaying multiple charts in one window in a grid-like orientation. By displaying the data set in a grid-like table, I want to see the underlying numerical data (ie, the actualy numbers) displayed in a grid window. Perhaps I can better explain what I mean by continuing with your example. When I run it, upon entering the line that reads "hist(randn(10000), 100) # lower right", my python prompt prints out the following: >>> hist(randn(10000), 100) # lower right (array([ 3, 0, 3, 5, 4, 10, 3, 5, 11, 2, 17, 9, 7, 17, 24, 31, 29, 38, 42, 36, 53, 57, 70, 79, 78, 84, 105, 103, 132, 158, 141, 164, 177, 172, 181, 217, 223, 243, 254, 258, 286, 276, 279, 279, 300, 312, 333, 280, 305, 270, 278, 278, 273, 257, 239, 223, 204, 216, 216, 174, 169, 142, 136, 120, 118, 102, 89, 79, 69, 60, 48, 55, 42, 37, 27, 31, 30, 25, 14, 12, 19, 12, 10, 5, 2, 5, 2, 2, 2, 1, 1, 3, 2, 2, 1, 2, 0, 0, 0, 1]), array([-3.35781891 57051, -3.21132211, -3.13807372, -3.06482532, -2.99157693, -2.91832853, -2.84508014, -2.77183174, -2.69858334, -2.62533495, -2.55208655, -2.47883816, -2.40558976, -2.33234137, -2.25909297, -2.18584457, -2.11259618, -2.03934778, -1.96609939, -1.89285099, -1.8196026 , -1.7463542 , -1.6731058 , -1.59985741, -1.52660901, -1.45336062, -1.38011222, -1.30686383, -1.23361543, -1.16036703, -1.08711864, -1.01387024, -0.94062185, -0.86737345, -0.79412506, -0.72087666, -0.64762826, -0.57437987, -0.50113147, -0.42788308, -0.35463468, -0.28138629, -0.20813789, -0.13488949, -0.0616411 , 0.0116073 , 0.08485569, 0.15810409, 0.23135248, 0.30460088, 0.37784928, 0.45109767, 0.52434607, 0.59759446, 0.67084286, 0.74409125, 0.81733965, 0.89058805, 0.96383644, 1.03708484, 1.11033323, 1.18358163, 1.25683002, 1.33007842, 1.40332682, 1.47657521, 1.54982361, 1.623072 , 1.6963204 , 1.76956879, 1.84281719, 1.91606558, 1.98931398, 2.06256238, 2.13581077, 2.20905917, 2.28230756, 2.35555596, 2.42880435, 2.50205275, 2.57530115, 2.64854954, 2.72179794, 2.79504633, 2.86829473, 2.94154312, 3.01479152, 3.08803992, 3.16128831, 3.23453671, 3.3077851 , 3.3810335 , 3.45428189, 3.52753029, 3.60077869, 3.67402708, 3.74727548, 3.82052387, 3.89377227])... To me, that isnt a fun way to look at (or attempt to edit) the numbers in my data set. I think it would be much more useful to display the numbers such as those above in a separate window. What if I have 5,000 data observations? A scrollable data grid window would make a much nicer display. The picture at http://freshmeat.net/screenshots/36907/39220/ gives the basic idea of what I mean by a data grid (though what I need is much more basic than that picture). Wx has such a grid widget which can be used for displaying/editing data, which is what I was hoping to use. However, I am not sure if one should mix different gui's. Iow, if I use tkagg or gtk as my interactive matplotlib gui, can I also display and interact with wxpython grid widgets in the same script smoothly? Am I asking for trouble having the same script display interactive matplotlib charts using one gui type and then display these grid widgets using another gui type? Or should I just stick with one gui type throughout the entire script so that the interactive matplotlib charts use say gtk and the same script also uses gtk for its grid widgets? I hope that makes more sense. Thanks again, Tom -----Original Message----- From: John Hunter [mailto:jdh...@ac...] Sent: Tuesday, August 17, 2004 12:59 PM To: Thomas Barket Cc: mat...@li... Subject: Re: [Matplotlib-users] Requesting advice on multi-threaded matplotlib session + grids displaying data >>>>> "Thomas" == Thomas Barket <tho...@ya...> writes: Thomas> Hello, I am fairly new to matplotlib in particular and Thomas> using gui's in general and don't have much experience yet Thomas> with threading. From a python command prompt, I want to Thomas> be able to use python to create and work with data sets, Thomas> while simultaneously be able to chart the data with Thomas> matplotlib. Since I would like to display more than one Thomas> matplotlib chart at a time, I presume this involves Thomas> working with threads. Furthermore, I would like to also Thomas> display the data sets in a grid-like table, and since I Thomas> want to see more than one such grid-like table at a time Thomas> (and of course see grid-like tables and matplotlib charts Thomas> at the same time too), I think this will also involve Thomas> threading. Have you had a chance to read http://matplotlib.sourceforge.net/interactive.html? This gives a little background on using matplotlib interactively. As stated on that page, the best approach with the current matplotlib (0.61) is to set backend : TkAgg interactive : True in your matplotlibrc file (http://matplotlib.sourceforge.net/faq.html#MATPLOTLIBRC). If you do this, you will not need to call show. Fernando Perez, author of ipython, is working on a much improved interactive shell for matplotlib + GTK. He plans eventually to support all the backends, but right now is focusing on GTK (tkagg already works with ipython). You will need CVS ipython and CVS matplotlib to try this out, but it is very nice. See his earlier post http://sourceforge.net/mailarchive/forum.php?thread_id=5323260&forum_id=3340 5 As for the grids, if I understand you correctly, the best way to do this is create multiple axes with the subplot command, eg, from matplotlib.matlab import * subplot(221) # upper left plot(range(10), 'go') subplot(222) pcolor(rand(10,10)) # upper right subplot(223) scatter(rand(12), rand(12)) # lower left subplot(224) hist(randn(10000), 100) # lower right show() Is this what you are looking for? [You can embed multiple matplotlib figure canvases into a wx grid or a gtk.Table if you want to use the GUI API, but I'm assuming you're looking for something simpler, as above]. JDH |
From: John H. <jdh...@ac...> - 2004-08-18 17:55:20
|
>>>>> "Thomas" == Thomas Barket <tho...@ya...> writes: Thomas> Btw, what does "TkAgg sets interactive mode to True when Thomas> you issue the show command" mean exactly? It means that if you are using tkagg and issue show, it launches the interactive interpreter (python shell) Thomas> Wx has such a grid widget which can be used for Thomas> displaying/editing data, which is what I was hoping to Thomas> use. However, I am not sure if one should mix different Thomas> gui's. Iow, if I use tkagg or gtk as my interactive Thomas> matplotlib gui, can I also display and interact with Thomas> wxpython grid widgets in the same script smoothly? Am I Thomas> asking for trouble having the same script display Thomas> interactive matplotlib charts using one gui type and then Thomas> display these grid widgets using another gui type? Or Thomas> should I just stick with one gui type throughout the Thomas> entire script so that the interactive matplotlib charts Thomas> use say gtk and the same script also uses gtk for its grid Thomas> widgets? OK, now I see better where you are coming from. You have a deluge of data coming back from the prompt in the interactive shell and are looking for a better way to deal with it. This is really beyond the scope of matplotlib since it is a plotting library and your question goes more to interacting with data. See ipython for solutions to facilitate better interaction with data. I can give you a couple of pointers though. If you save the return value of a plot as a named variable, the output will be suppressed. Then you can use array slicing to only show a portion of it. 1 >>> n, bins, patches = hist(randn(10000), 100) # no output printed 2 >>> n[:5] # look at your data in slices using indexing Out[2]: [1,1,2,5,3,] ipython has additional features to automatically suppress really large arrays 1 >>> rand(100,100) Out[1]: array (100,100) , type = d, has 10000 elements On to your question about mixing GUIs. Don't do it. You will explode. If you want to display your data in a wx grid, you could use the wxagg matplotlib backend and write some functions to display the data in a wx grid. Eg, if you are working in a shell that supports wx interactive work (pycrust), you could write a function to display any array or vector in a wx grid and then call that function interactively. Fernando is working on an interactive shell (mentioned previously) that supports matplotlib/gtk. Once he gets the kinks worked out, he plans to support matplotlib/wx as well. If you want to work in gtk (eg matplotlib/gtkagg) the equivalent to a wx grid is a treeview/liststore. You can write functions to pipe arrays into grids and then display them by calling that function interactively. Here is an example using Fernando's ipython-gtk hunter:~/python/examples/pygtk> python ~/tmp/ip/ipython-gtk.py Extra content at the end of the document Python 2.3.2 (#1, Oct 13 2003, 11:33:15) [GCC 3.3.1] on linux2 Type "copyright", "credits" or "license" for more information. (MatplotlibShell) 1 >>> from matplotlib.numerix import rand 2 >>> from array_to_grid import view_array 3 >>> view_array( rand(20,10)) Out[3]: <ArrayView object (GtkWindow) at 0x4136db94> And this is the screenshot - http://nitace.bsd.uchicago.edu:8080/files/share/Screenshot-Ipython-gtk.py.png While it would be possible for us to write functions in matplotlib that would implement view_array (or something like it) for each of the GUI backends, allowing you to call this function for tk, wx or gtk, it's really beyond the scope of matplotlib (we're busy enough trying to plot!). It's more in the domain of a matlab / mathematica like integrated scientific computing environment, another topic near and dear to Fernando's heart. Here is the code array_to_grid.py - you can do a lot more with treeviews and liststores, eg make a proper editable spreadsheet interface with scroll bars in both x and y directions, but this will get you started 'Display an array as a treeview' import pygtk pygtk.require('2.0') import gobject import gtk from gtk import gdk def view_array(X): 'instantiate an ArrayView instance and show it' grid = ArrayView(X) grid.show_all() return grid class ArrayView(gtk.Window): def __init__(self, X): gtk.Window.__init__(self) self.numRows, self.numCols = X.shape self.data = X self.set_title('Array display') self.set_border_width(8) vbox = gtk.VBox(False, 8) self.add(vbox) sw = gtk.ScrolledWindow() sw.set_shadow_type(gtk.SHADOW_ETCHED_IN) sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) vbox.pack_start(sw, True, True) model = self.create_model() self.treeview = gtk.TreeView(model) self.treeview.set_rules_hint(True) sw.add(self.treeview) self.add_columns() self.set_default_size(640, 480) self.add_events(gdk.BUTTON_PRESS_MASK | gdk.KEY_PRESS_MASK| gdk.KEY_RELEASE_MASK) def add_columns(self): model = self.treeview.get_model() renderer = gtk.CellRendererText() for i in range(self.numCols): column = gtk.TreeViewColumn('%d'%i, gtk.CellRendererText(), text=i) self.treeview.append_column(column) def create_model(self): types = [gobject.TYPE_DOUBLE]*self.numCols store = gtk.ListStore(*types) for row in self.data: iter = store.append() pairs = [] for i, num in enumerate(row): pairs.extend((i, num)) store.set(iter, *pairs) return store if __name__=='__main__': from matplotlib.numerix import rand view_array(rand(10,10)) gtk.main() |
From: Thomas B. <tho...@ya...> - 2004-08-20 09:40:50
|
John, That makes sense. Tks vm. I am still confused on what approach needs to be taken to get the data grids to be *interactive* from the python command prompt. It seems to me that such interactivity requires threading (ie, creating any new data grid gui window in its own thread). Is that correct, or is there some other way to do it? In fact, with the example below, in order to get it to work, I needed to add a couple of lines to call the mainloop: >>> from matplotlib.numerix import rand >>> from array_to_grid import view_array >>> view_array( rand(20,10)) <ArrayView object (GtkWindow) at 0x1136eb8> >>> import gtk >>> gtk.main() After I call gtk.main(), I then lose all ability to interact with the python command prompt :-(. This gui mainloop concept is something I am a little confused on. I understand why one has to call such a mainloop for a gui: so the gui window can be alerted by the os that some kind of event has been fired, like a mouse click, so it can respond in the appropriate manner. But I don't want to create an application that takes over the mainloop. I am not writing a window-driven application. I want to continue to interact with the python command prompt (and hopefully be able to interact with any launched gui windows from it). So I suppose I have to figure out how to get such mainloops to run in separate threads (or is "process" the correct word here???) in order to have access to the python command prompt (and possibly even create more data grids!). Is that correct? Im also a little confused bc I have read statements like "all graphics commands should be handled in a single thread." The "Thinking in Tkinter" web site (http://www.ferg.org/thinking_in_tkinter/index.html) says: Note that you should not run these programs under IDLE. IDLE is itself a Tkinter application, with its own "mainloop" that will conflict with the mainloop in these programs. If you really want to view and run these programs using IDLE, then -- for each program -- you should comment out the "mainloop" statement in the program before running it. That kind of warning sounds a little depressing. Is it not possible to (somewhat easily) launch various gui windows, like a data grid, in their own threads (processes?) and still have control of the python command prompt and be able to interact with such gui windows? Any pointers anyone can give me to learn more about launching interactive gui widgets from the python command prompt and maintaining interactivity with the python command prompt would be greatly appreciated. Many thanks once again. Sincerely, Tom -----Original Message----- From: John Hunter [mailto:jdh...@ac...] Sent: Wednesday, August 18, 2004 1:31 PM To: Thomas Barket Cc: mat...@li... Subject: Re: [Matplotlib-users] Requesting advice on multi-threaded matplotlib session + grids displaying data >>>>> "Thomas" == Thomas Barket <tho...@ya...> writes: Thomas> Btw, what does "TkAgg sets interactive mode to True when Thomas> you issue the show command" mean exactly? It means that if you are using tkagg and issue show, it launches the interactive interpreter (python shell) Thomas> Wx has such a grid widget which can be used for Thomas> displaying/editing data, which is what I was hoping to Thomas> use. However, I am not sure if one should mix different Thomas> gui's. Iow, if I use tkagg or gtk as my interactive Thomas> matplotlib gui, can I also display and interact with Thomas> wxpython grid widgets in the same script smoothly? Am I Thomas> asking for trouble having the same script display Thomas> interactive matplotlib charts using one gui type and then Thomas> display these grid widgets using another gui type? Or Thomas> should I just stick with one gui type throughout the Thomas> entire script so that the interactive matplotlib charts Thomas> use say gtk and the same script also uses gtk for its grid Thomas> widgets? OK, now I see better where you are coming from. You have a deluge of data coming back from the prompt in the interactive shell and are looking for a better way to deal with it. This is really beyond the scope of matplotlib since it is a plotting library and your question goes more to interacting with data. See ipython for solutions to facilitate better interaction with data. I can give you a couple of pointers though. If you save the return value of a plot as a named variable, the output will be suppressed. Then you can use array slicing to only show a portion of it. 1 >>> n, bins, patches = hist(randn(10000), 100) # no output printed 2 >>> n[:5] # look at your data in slices using indexing Out[2]: [1,1,2,5,3,] ipython has additional features to automatically suppress really large arrays 1 >>> rand(100,100) Out[1]: array (100,100) , type = d, has 10000 elements On to your question about mixing GUIs. Don't do it. You will explode. If you want to display your data in a wx grid, you could use the wxagg matplotlib backend and write some functions to display the data in a wx grid. Eg, if you are working in a shell that supports wx interactive work (pycrust), you could write a function to display any array or vector in a wx grid and then call that function interactively. Fernando is working on an interactive shell (mentioned previously) that supports matplotlib/gtk. Once he gets the kinks worked out, he plans to support matplotlib/wx as well. If you want to work in gtk (eg matplotlib/gtkagg) the equivalent to a wx grid is a treeview/liststore. You can write functions to pipe arrays into grids and then display them by calling that function interactively. Here is an example using Fernando's ipython-gtk hunter:~/python/examples/pygtk> python ~/tmp/ip/ipython-gtk.py Extra content at the end of the document Python 2.3.2 (#1, Oct 13 2003, 11:33:15) [GCC 3.3.1] on linux2 Type "copyright", "credits" or "license" for more information. (MatplotlibShell) 1 >>> from matplotlib.numerix import rand 2 >>> from array_to_grid import view_array 3 >>> view_array( rand(20,10)) Out[3]: <ArrayView object (GtkWindow) at 0x4136db94> And this is the screenshot - http://nitace.bsd.uchicago.edu:8080/files/share/Screenshot-Ipython-gtk.py.pn g While it would be possible for us to write functions in matplotlib that would implement view_array (or something like it) for each of the GUI backends, allowing you to call this function for tk, wx or gtk, it's really beyond the scope of matplotlib (we're busy enough trying to plot!). It's more in the domain of a matlab / mathematica like integrated scientific computing environment, another topic near and dear to Fernando's heart. Here is the code array_to_grid.py - you can do a lot more with treeviews and liststores, eg make a proper editable spreadsheet interface with scroll bars in both x and y directions, but this will get you started 'Display an array as a treeview' import pygtk pygtk.require('2.0') import gobject import gtk from gtk import gdk def view_array(X): 'instantiate an ArrayView instance and show it' grid = ArrayView(X) grid.show_all() return grid class ArrayView(gtk.Window): def __init__(self, X): gtk.Window.__init__(self) self.numRows, self.numCols = X.shape self.data = X self.set_title('Array display') self.set_border_width(8) vbox = gtk.VBox(False, 8) self.add(vbox) sw = gtk.ScrolledWindow() sw.set_shadow_type(gtk.SHADOW_ETCHED_IN) sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) vbox.pack_start(sw, True, True) model = self.create_model() self.treeview = gtk.TreeView(model) self.treeview.set_rules_hint(True) sw.add(self.treeview) self.add_columns() self.set_default_size(640, 480) self.add_events(gdk.BUTTON_PRESS_MASK | gdk.KEY_PRESS_MASK| gdk.KEY_RELEASE_MASK) def add_columns(self): model = self.treeview.get_model() renderer = gtk.CellRendererText() for i in range(self.numCols): column = gtk.TreeViewColumn('%d'%i, gtk.CellRendererText(), text=i) self.treeview.append_column(column) def create_model(self): types = [gobject.TYPE_DOUBLE]*self.numCols store = gtk.ListStore(*types) for row in self.data: iter = store.append() pairs = [] for i, num in enumerate(row): pairs.extend((i, num)) store.set(iter, *pairs) return store if __name__=='__main__': from matplotlib.numerix import rand view_array(rand(10,10)) gtk.main() |