[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 

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

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
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
		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 = []

	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
		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.graph.line_create(name, xdata = tuple(self.datax[dataset]), ydata = tuple(self.datay[dataset]), color = color, symbol = '')
			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.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)
				(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):

	def Remove(self):

	def Save(self):

# 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