[chimera-dev] examples of 2-D plotting in plugins?

David A. C. Beck dacb at u.washington.edu
Mon Nov 3 16:08:19 PST 2008


Since the topic was examples, I have attached is a hacked out snippet from 
some of our code.  It produces a window that reads some 2D data from a 
set of files.  The hack comes in to make this code work outside of our 
module and read files instead of sockets / i/o buffers.  Notice the 
hardcoded path: /tmp/chimera-dev at cgl.ucsf.edu where the files e.dat, 
ek.dat, ep.dat, secs.dat and t.dat need to exist.  The format of these 
files is space separated two columns: the first being simulation timestep 
the second is the value (e.dat -> total energy, ek.dat -> kinetic energy, 
ep.dat -> potential energy, secs.dat -> time in seconds per simulation 
block, and t.dat -> temperature).  The Add and Remove buttons are 
disabled.  Only the mouseUp, mouseDrag and mouseDown methods are 
implemented.

The python code is in 'plot2d.py' and the toolbar icon is 'plot.png'. 
YMMV.

While I was looking at this, I noticed a note in my margin that says 'look 
at MinrmsPlot / ActivePlot.'  So the original poster may be interested in 
looking at that code for some more plot window examples...

--
David A. C. Beck, Ph.D.
dacb at u.washington.edu
Valerie Daggett Laboratory
University of Washington, Seattle

On Mon, 3 Nov 2008, Eric Pettersen wrote:

> Hey, negative experiences are valuable to know about too!  The more info we 
> have for making a decision, the better.  We do have practice with making 
> recalcitrant builds bend to our will though. :-)
>
> --Eric
>
> On Nov 3, 2008, at 3:09 PM, David A. C. Beck wrote:
>
>> Sorry for the quick response, I can flesh it out in some more detail if
>> anyone is interested...
>> 
>> We have used BLT2 to display 2D graphs from inside Chimera.  The input are
>> typically energies or other emissions as a function of simulation time
>> from our simulation software (ilmm) that interfaces with Chimera.  I
>> never found a way to update the graph in real time (even though we can
>> pump the data in over a socket from the simulation code). Instead the
>> Pmw.Blt.Graph object has to be reloaded.  There must be a way around
>> this.  The graphs are ugly and not in any way acceptable for publication.
>> 
>> The experience of getting everything to build against the correct
>> headers and python libraries was frustrating.  The distribution to
>> machines in our lab is kludgy at best.  I've never gotten it working
>> under Windows or Mac.  In case there is any doubt from my tone, we really
>> don't like the BLT solution.
>> 
>> Some of my notes on getting it to work with an older version of Chimera:
>> 
>> BLT info:
>> 
>> Configure command for BLT to w/ with Daggett Lab chimera installation:
>> ./configure --prefix=/net/programs/chimera/lib 
>> --with-tkincls=/net/programs/chimera/include 
>> --with-tclincls=/net/programs/chimera/include 
>> --with-blt=/net/programs/chimera/lib 
>> --with-tcllibs=/net/programs/chimera/lib 
>> --with-tklibs=/net/programs/chimera/lib
>> 
>> make install for BLT is broken, and must be finished by hand;  run make 
>> install, copy the libraries (.so) from
>> /var/tmp/chimeraBuild/build/foreign/tcl8.4.2.16/lib to 
>> /net/programs/chimera/lib, then move the /net/programs/chimera/lib/blt2.4 
>> directory into /net/programs/chimera/lib/tcl8.4
>> it seems that the stuff in /var/tmp/chimeraBuild/build/foriegn... has to be 
>> there for this to work
>> 
>> --
>> David A. C. Beck, Ph.D.
>> dacb at u.washington.edu
>> Valerie Daggett Laboratory
>> University of Washington, Seattle
>> 
>> On Mon, 3 Nov 2008, Eric Pettersen wrote:
>> 
>>> FYI, the last paragraph of my reply below may be of general interest to
>>> developers interested in plotting data...
>>> 
>>> On Oct 31, 2008, at 10:09 AM, Randy Heiland wrote:
>>> 
>>>> Hi gang,
>>>> 
>>>> For one of the Chimera plugins that I now maintain, I'm considering
>>>> eliminating the use of matplotlib and wondering if Chimera's innards
>>>> are capable of doing what I want.  For starters, are there any
>>>> example plugins, etc that demonstrate how one could do simple
>>>> plotting and simple (image) contours?  In addition, I'd need to
>>>> handle mouse events, e.g. to retrieve x,y positions on the contour
>>>> image.
>>> 
>>> Hi Randy,
>>> 	I'm thinking that what Chimera currently provides will not be an
>>> adequate replacement for the capabilities of matplotlib that NLOPredict 
>>> uses.
>>> Aside from the basic Tk widgets themselves (the most salient of which is
>>> Canvas) the only relevant widgets I can think of is an interactive 
>>> histogram
>>> widget in CGLtk.Histogram, and a basic line/point plotting widget 
>>> available
>>> through Scientific.TkWidgets.TkPlotCanvas
>>> (Scientific.TkWidgets.TkPlotCanvas).
>>> 	But I think NLOPredict needs interactive contour and bar graphs.  As
>>> long as you can generate the contour image yourself somehow, I think you 
>>> can
>>> pretty easily gin up an interactive contour plot using the Image item of
>>> Tk.Canvas.  As for the bar graph, would BLT (A User's Guide to Pmw.Blt)
>>> provide enough functionality if we decided to provide that?  It seems to
>>> provide bar charts (A complete reference to the Pmw.Blt plot widget).  It
>>> also might or might not be easier for you to provide BLT for NLOPredict as 
>>> a
>>> stopgap measure.
>>> 	So the Chimera developers will be discussing possibly providing some
>>> kind of plotting library at our next weekly meeting.  Clearly, matplotlib 
>>> is
>>> the "Cadillac" of plotting libraries.  And like a Cadillac it has the
>>> downside of large size -- probably in the range of 60-80MB before
>>> compression.  It also has the drawback of depending on a lot of other
>>> packages which we would also have to include and port to all our supported
>>> platforms, including 64-bit versions thereof.  So I guess the question is
>>> whether we could get away with including something smaller like BLT, which 
>>> we
>>> would also be able to deploy more quickly due to the lower effort 
>>> involved,
>>> or do people really need the unique capabilities of matplotlib?  Anybody?
>>> 
>>> --Eric
>>>
>>>                     Eric Pettersen
>>>                     UCSF Computer Graphics Lab
>>>                     http://www.cgl.ucsf.edu
>>> 
>> _______________________________________________
>> Chimera-dev mailing list
>> Chimera-dev at cgl.ucsf.edu
>> http://www.cgl.ucsf.edu/mailman/listinfo/chimera-dev
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: plot.png
Type: image/png
Size: 995 bytes
Desc: 
URL: <http://plato.cgl.ucsf.edu/pipermail/chimera-dev/attachments/20081103/0b7a8617/attachment.png>
-------------- next part --------------
import Pmw
from MinrmsPlot import ActivePlot

class ilmmPlotDialog(chimera.baseDialog.ModelessDialog):
	"ilmm Plot Window"

	name = "ilmm Plot Window"
	buttons = ("Add...", "Remove...", "Save...", "Close")
	help = ("ilmmPlotWindow.html", ilmm)
	title = "ilmm plot window"

	def fillInUI(self, parent):
		self.x0 = self.y0 = self.x1 = self.y1 = 0
		parent.focus_set()
		self.graph = Pmw.Blt.Graph(parent)
		self.graph.pack(expand = 1, fill = "both")
		self.graph.bind(sequence = "<ButtonPress>",   func = self.mouseDown)
		self.graph.bind(sequence = "<ButtonRelease>", func = self.mouseUp  )
		self.datax = []
		self.datay = []
		self.LoadData()

	def LoadData(self):
		datagroups = [["Total Energy", "e.dat", "black"], ["Kinetic Energy", "ek.dat", "green"], ["Potential Energy", "ep.dat", "blue"], ["Seconds / ps", "secs.dat", "yellow"], ["Temperature", "t.dat", "red"]]
		dataset = 0
		self.datax.append([])
		self.datay.append([])
		for group in datagroups:
			[name, filename, color] = group
			fullfilename = "/tmp/chimera-dev at cgl.ucsf.edu/" % filename
			file = open(fullfilename, 'r')
			for line in file.readlines():
				[x, y] = string.split(line, ' ')
				self.datax[dataset].append(float(x))
				self.datay[dataset].append(float(y))
			file.close()
			self.graph.line_create(name, xdata = tuple(self.datax[dataset]), ydata = tuple(self.datay[dataset]), color = color, symbol = '')
			self.datax.append([])
			self.datay.append([])
			dataset = dataset + 1

	def zoom(self, x0, y0, x1, y1):
		self.graph.xaxis_configure(min = x0, max = x1)
		self.graph.yaxis_configure(min = y0, max = y1)

	def mouseDrag(self, event):
		(self.x1, self.y1) = self.graph.invtransform(event.x, event.y)
		self.graph.marker_configure("marking rectangle", coords = (self.x0, self.y0, self.x1, self.y0, self.x1, self.y1, self.x0, self.y1, self.x0, self.y0))

	def mouseUp(self, event):
		if self.dragging:
			self.graph.unbind(sequence="<Motion>")
			self.graph.marker_delete("marking rectangle")
		if self.x0 <> self.x1 and self.y0 <> self.y1:
			# make sure the coordinates are sorted
			if self.x0 > self.x1: self.x0, self.x1 = self.x1, self.x0
			if self.y0 > self.y1: self.y0, self.y1 = self.y1, self.y0
			if event.num == 1:
				self.zoom(self.x0, self.y0, self.x1, self.y1)
			else:
				(X0, X1) = self.graph.xaxis_limits()
				k  = (X1 - X0)/ (self.x1 - self.x0)
				self.x0 = X0 - (self.x0 - X0) * k
				self.x1 = X1 + (X1 - self.x1) * k
				(Y0, Y1) = self.graph.yaxis_limits()
				k  = (Y1 - Y0) / (self.y1 - self.y0)
				self.y0 = Y0 - (self.y0 - Y0) * k
				self.y1 = Y1 + (Y1 - self.y1) * k
				self.zoom(self.x0, self.y0, self.x1, self.y1)

	def mouseDown(self, event):
		self.dragging = 0
		if self.graph.inside(event.x, event.y):
			self.dragging = 1
			(self.x0, self.y0) = self.graph.invtransform(event.x, event.y)
			self.graph.marker_create("line", name = "marking rectangle", dashes = (2, 2))
			self.graph.bind(sequence = "<Motion>",  func = self.mouseDrag)

	def Add(self):
		pass

	def Remove(self):
		pass

	def Save(self):
		pass

# register the dialog with chimera
chimera.dialogs.register(ilmmPlotDialog.name, ilmmPlotDialog)

# add its callback to the toolbar
dir, file = os.path.split(__file__)
icon = os.path.join(dir, 'plot.png')
chimera.tkgui.app.toolbar.add(icon, lambda d=chimera.dialogs.display, n=ilmmPlotDialog.name: d(n), ilmmPlotDialog.title, None)


More information about the Chimera-dev mailing list