matplotlib -- http://matplotlib.sourceforge.net/ is the by far the best 2-D plotting package I've encountered in python.

John

Jim Leven wrote:
[pygtk] Pygtk simple graphics lib

Friends

I have been using a simple module employing Tkinker
and Canvas for plotting graphs and models (attached)
and I would now like to incorporate an interactive
component into this program.  I have used
pygtk to provide a gui for parameter selection
elsewhere and would like to convert all to pygtk.

Is there a recommended pygtk module to draw graphs,
and polygonal models, and to interactively select or
move points in these?  I would be grateful for advice.

Regards
Jim Leven

Email : [EMAIL PROTECTED]


#!/usr/bin/python from Tkinter import * from Canvas import Line, CanvasText import string import math # from utils import * from math import pi

class plt:

    root      = None
    __canvas  = None
    __xfact   = None
    __xmin    =  None
    __yfact   = None
    __ymin    = None
    __xorigin = None
    __yorigin = None
    __x1      = None
    __x2      = None
    __y1      = None
    __y2      = None
    __xc      = 0		# current x position
    __yc      = 0		# current y position
    __current_colour = "black"
    __current_width  = 1
    __font           = "Times 16 italic bold"

    def __init__(self, xpix, ypix ) :
        self.root = Tk()
        self.__x1 = 0
        self.__x2 = xpix
        self.__y1 = 0
        self.__y2 = ypix
        self.__canvas = Canvas(self.root, height=ypix, width=xpix, background="")
	#self.__Quit = Button(self.root, text="Quit", command=self.root.quit).pack(side=TOP)
	self.__Quit = Button(self.root, text="Quit", command=self.root.quit).pack(side=BOTTOM)

    def pack( self ) :
        self.__canvas.pack()

    def scale(self, xu1, xu2, yu1, yu2 ):
      """
       sets up the scaling parameters, 
	xu1 and xu2 are the x units in user coordinates
	yu1 and yu2 are the y units in user coordinates
      """
      self.__xfact = (self.__x2 - self.__x1) / (xu2 - xu1)
      self.__xmin =  xu1
      self.__yfact = (self.__y2 - self.__y1) / (yu2 - yu1)
      self.__ymin = yu1

      self.__xorigin = self.__x1
      self.__yorigin = self.__y1


    def plot(self, x, y ) :
	xp = self.__xorigin + (x - self.__xmin ) * self.__xfact
        yp = self.__yorigin + (y - self.__ymin ) * self.__yfact
        self.__canvas.create_line( self.__xc, self.__yc, xp, yp, \
		fill=self.__current_colour, width=self.__current_width )
	self.__xc = xp
	self.__yc = yp


    def move(self, x, y ) :
	self.__xc = self.__xorigin + (x - self.__xmin ) * self.__xfact
        self.__yc = self.__yorigin + (y - self.__ymin ) * self.__yfact



    def pxax ( self, y, xst, xfin, tick ) :
        """
        plots an x-axis at the y value from xst to xfin
        with ticks spaced "tick" apart
        if "tick" puts the first tick beyond xfin then no ticks
        """

	if xst == xfin  : 
		return
	if  xst < xfin  :
		xfirst = xst 
                xlast  = xfin
	else : 
		xfirst = xfin
                xlast  = xst

	self.move ( xst, y )
	x1 = math.floor(xfirst/tick)*tick
	k = int( (xlast - x1) / tick + 2 )
	for i in range (k) :
	   x = x1 + i * tick
	   self.plot ( x, y );
           self.__canvas.create_line( self.__xc, self.__yc, self.__xc, self.__yc+7, \
		fill=self.__current_colour, width=self.__current_width )
	self.plot ( xlast, y )


    def set_colour ( self, colour ) :
        self.__current_colour = colour


    def set_font ( self, font ) :
        self.__font = font


    def add_text ( self, x, y, txt, just="center", anc="center" ) :
	   qxc = self.__xorigin + (x - self.__xmin ) * self.__xfact
           qyc = self.__yorigin + (y - self.__ymin ) * self.__yfact
           self.__canvas.create_text( qxc, qyc, text=txt, justify=just, \
		font=self.__font, anchor=anc )


    def set_line_width ( self, lsize ) :
        self.__current_width  = lsize


    def pxlab ( self, y, xst, xfin, tick ) :
	"""
	label an x-axis at y, starting at xst and ending at     
	  xfin, with labels spaced "tick" apart.                
	"""

	if ( xst == xfin ) : return
	if (xst < xfin ) :
		xfirst = xst 
		xlast  = xfin 
	else : 
		xfirst = xfin
		xlast = xst
	x1 = math.floor(xfirst/tick)*tick
	k = int( (xlast - x1) / tick + 2 )
	for i in range (k) :
	   x = x1 + i * tick
	   qxc = self.__xorigin + (x - self.__xmin ) * self.__xfact
           qyc = self.__yorigin + (y - self.__ymin ) * self.__yfact
           self.__canvas.create_text( qxc, qyc, text=str(x), anchor="s", justify="center" )


    def pxtic ( self, yp, yn ) :
	"""
	       produces a tick of yp up and yn down from present position
	       where yp and yn are in millimetres >= 0 */
	"""
        self.__canvas.create_line( self.__xc, self.__yc+yn, self.__xc, self.__yc-yp, 
		fill=self.__current_colour, width=self.__current_width )

	
    def pyax ( self, x, yst, yfin, tick ) :
	"""
        plots an y-axis at the x value from yst to yfin
         with ticks spaced "tick" apart
	"""
	if ( yst == yfin )  : return
	if  yst < yfin :
	   yfirst = yst 
	   ylast  = yfin
	else: 
	   yfirst = yfin
	   yfirst = yst
	self.move ( x, yfirst )
	y1 = math.floor(yfirst/tick)*tick
	k = int ( (ylast - y1) / tick + 1 )
	for i in range (k) :
	   y = y1 + (i+1) * tick
	   self.plot ( x, y );
           self.__canvas.create_line( self.__xc, self.__yc, self.__xc+7, self.__yc, \
		fill=self.__current_colour, width=self.__current_width )
	self.plot ( x, ylast )

	
    def pyaxr ( self, x, yst, yfin, tick ) :
	"""
        plots a RHS y-axis at the x value from yst to yfin
        with ticks spaced "tick" apart
	"""
	if ( yst == yfin )  : return
	if  yst < yfin :
	   yfirst = yst 
	   ylast  = yfin
	else: 
	   yfirst = yfin
	   yfirst = yst
	self.move ( x, yfirst )
	y1 = math.floor(yfirst/tick)*tick
	k = int ( (ylast - y1) / tick + 2 )
	for i in range (k) :
	   y = y1 + i * tick
	   self.plot ( x, y );
           self.__canvas.create_line( self.__xc, self.__yc, self.__xc-4, self.__yc, \
		fill=self.__current_colour, width=self.__current_width )
	self.plot ( x, ylast )



    def pylab ( self, x, yst, yfin, tick ) :
	"""
	   label an y-axis at x, starting at yst and ending at
	     yfin, with labels spaced "tick" apart.
	"""

	if ( yst == yfin ) : return
	if (yst < yfin ) :
		yfirst = yst 
		ylast  = yfin 
	else : 
		yfirst = yfin
		ylast = yst
	
	y1 = math.floor(yfirst/tick)*tick
	k = int ( (ylast - y1) / tick + 1 )
	for i in range (k) :
	   y = y1 + (i+1) * tick
	   qxc = self.__xorigin + (x - self.__xmin ) * self.__xfact - 6
           qyc = self.__yorigin + (y - self.__ymin ) * self.__yfact
           self.__canvas.create_text( qxc, qyc, text=str(y), anchor="e", justify="left" )



    def pytic ( self, xp, xn ) :
	"""
	produces a tick of xp left and xn right from present position
	where xp and xn are in pixels
	"""
        self.__canvas.create_line( self.__xc-xp, self.__yc, self.__xc+xn, self.__yc, 
		fill=self.__current_colour, width=self.__current_width )


    def pcircl ( self, x, y, siz ) :
	"""
        plot the circle symbol at the point x,y with radius siz pixel
	"""
	qxc = self.__xorigin + (x - self.__xmin ) * self.__xfact
        qyc = self.__yorigin + (y - self.__ymin ) * self.__yfact
	# self.move ( x, y )
        self.__canvas.create_arc( qxc-siz, qyc-siz, \
		qxc+siz, qyc+siz, start = 0, extent=359.9, \
		fill=self.__current_colour, width=self.__current_width )



    def nice_tick ( self, q1, q2, n ) :
	"""
	To get "nice" values for the plotting of axes
  	input q1  : min value
  	input q2  : max value
  	input n   : approx no. of intervals
  	return q3 : new min.
  	return dq : New interval
	"""

      	if ( n < 0 ) : return 0.0, 0.0
      	deltaq = math.fabs(q2-q1) / n
      	if ( deltaq <= 0.0 ) : return 0.0, 0.0
      	r  = math.log10 ( deltaq )
      	if ( r >= 0.0 ) :
	 ir = int( r )
      	else :
	 ir = int (r) - 1
      	fr = r - ir

      	deltaq = 10
      	if ( fr < 0.90309 )   : deltaq = 5.0
      	if ( fr < 0.4771212 ) : deltaq = 2.5
      	if ( fr < 0.25527 )   : deltaq = 1.0

      	deltaq = deltaq * math.exp ( ir * math.log(10) )
      	dq = deltaq
        if  q1 < q2 :
          ir = q1
        else :
          ir = q2
      
      	ir  = int (ir / deltaq)
      	if ( ir < 0 ) : ir = ir - 1
      	q3 = ir * deltaq
        if ( q3 < -dq ) : q3 = q3 + dq
        return q3, dq

#******************************************************************/

if __name__ == '__main__':

    P = plt( 900, 600)
 
    P.scale ( 0, 10, 0, 10 )

    P.set_colour (  "pink" ) 
    P.set_line_width ( 2 ) 
    P.move (1, 1)
    P.plot (5, 2)
    P.plot (1, 6)
    P.set_colour (  "red" ) 

    P.pcircl (  7, 7, 30 ) 

    x1, dx = P.nice_tick ( 1.1, 4.9, 8 ) 
    y1, dy = P.nice_tick ( 1.1, 7.0, 8 ) 
    P.pxax (  y1, x1, 5, dx ) 
    P.pxlab ( y1, x1, 5, dx ) 

    P.pyax (  x1, y1, 7, dy ) 
    P.pylab (  x1, y1, 7, dy ) 

    P.add_text (  2, 3, "(2,3)", just="center", anc="center" ) 
    P.set_font( "Times 24 bold" )

    P.move (4, 8)
    P.pxtic (  10, 10 ) 
    P.pytic (  10, 10 ) 
    P.add_text (  4, 8, "(4,8)", just="center", anc="center" ) 

    P.pyaxr ( 5, 1, 7, 0.5 ) 
    P.move ( 5, 7 ) 
    P.plot ( 1, 7 ) 

    P.set_colour (  "purple" ) 
    P.pcircl (  6, 7, 10 ) 

    P.set_colour (  "green" ) 
    P.set_line_width ( 3 ) 
    for k in range (100, 500, 1) :
      x = k / 100.0
      y = math.cos ( (x-1.0) / 4.0 * pi ) * 3.0 + 4.0
      P.plot ( x, y )

    P.pack()

    P.root.mainloop()
  

_______________________________________________ pygtk mailing list [email protected] http://www.daa.com.au/mailman/listinfo/pygtk Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/
_______________________________________________
pygtk mailing list   [email protected]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/

Reply via email to