Index: /issm/trunk-jpl/src/m/classes/pairoptions.py
===================================================================
--- /issm/trunk-jpl/src/m/classes/pairoptions.py	(revision 13410)
+++ /issm/trunk-jpl/src/m/classes/pairoptions.py	(revision 13411)
@@ -41,5 +41,5 @@
 			else:
 				#option is not a string, ignore it
-				print "WARNING: option number %d '%s' is not a string and will be ignored." % (i+1,type(arg[2*i]))
+				print "WARNING: option number %d is not a string and will be ignored." % (i+1)
 	# }}}
 
@@ -128,15 +128,17 @@
 	# }}}
 
-#	function num = fieldoccurences(obj,field), % {{{
-#	%FIELDOCCURENCES - get number of occurence of a field
-#
-#		%check input 
-#		if ~ischar(field),
-#			error('fieldoccurences error message: field should be a string');
-#		end
-#
-#		%get number of occurence
-#		num=sum(strcmpi(field,obj.list(:,1)));
-#	end % }}}
+	#def fieldoccurences(self,field): #{{{
+	#	'''
+	#	FIELDOCCURENCES - get number of occurence of a field
+	#	'''
+	#
+	#	#check input 
+	#	if not isinstance(field,(str,unicode)):
+	#		raise TypeError("fieldoccurences error message: field should be a string")
+
+	#	#get number of occurence
+	#	# ??
+	#	#return num
+	#	#% }}}
 
 	def getfieldvalue(self,field,default=None):    # {{{
Index: /issm/trunk-jpl/src/m/classes/plotoptions.py
===================================================================
--- /issm/trunk-jpl/src/m/classes/plotoptions.py	(revision 13411)
+++ /issm/trunk-jpl/src/m/classes/plotoptions.py	(revision 13411)
@@ -0,0 +1,125 @@
+from collections import OrderedDict, Counter, defaultdict
+from pairoptions import *
+
+class plotoptions(object):
+	'''
+	PLOTOPTIONS class definition
+
+		Usage:
+			plotoptions=plotoptions(*arg)
+	'''
+
+	def __init__(self,*arg):
+		self.numberofplots = 0
+		self.figurenumber  = 1
+		self.list          = OrderedDict()
+
+		self.buildlist(*arg)
+
+	def __repr__(self): #{{{
+		s="\n"
+		s+="	numberofplots: %i\n" % self.numberofplots
+		s+="	figurenumber: %i\n"  % self.figurenumber
+		if self.list:
+			s+="	list: (%ix%i)\n" % (len(self.list),2)
+			for item in self.list.iteritems():
+				#s+="	options of plot number %i\n" % item
+				if   isinstance(item[1],(str,unicode)):
+					s+="	field: %-10s value: '%s'\n" % (item[0],item[1])
+				elif isinstance(item[1],(bool,int,long,float)):
+					s+="	field: %-10s value: '%g'\n" % (item[0],item[1])
+				else:
+					s+="	field: %-10s value: '%s'\n" % (item[0],item[1])
+		else:
+			s+="	list: empty\n"
+		return s
+	#}}}
+	def buildlist(self,*arg): #{{{
+		#check length of input
+		if len(arg) % 2:
+			raise TypeError('error: an even number of options is required')
+
+		#go through args and build list (like pairoptions)
+		rawoptions=pairoptions(*arg)
+		numoptions=len(arg)/2
+		rawlist=[] # cannot be a dict since they do not support duplicate keys
+
+		for i in xrange(numoptions):
+			if isinstance(arg[2*i],(str,unicode)):
+				rawlist.append([arg[2*i],arg[2*i+1]])
+			else:
+				#option is not a string, ignore it
+				print "WARNING: option number %d is not a string and will be ignored." % (i+1)
+
+		#get figure number 
+		self.figurenumber=rawoptions.getfieldvalue('figure',1)
+
+		#get number of subplots 
+		numberofplots=Counter(x for sublist in rawlist for x in sublist if isinstance(x,(str,unicode)))['data']
+		self.numberofplots=numberofplots
+
+		#figure out whether alloptions flag is on
+		if rawoptions.getfieldvalue('alloptions','off') is 'on':
+			allflag=1
+		else:
+			allflag=0
+
+		#initialize self.list (will need a list of dict's (or nested dict) for numberofplots>1)
+		#self.list=defaultdict(dict)
+		for i in xrange(numberofplots):
+			self.list[i]=pairoptions()
+
+		#process plot options
+		for i in xrange(len(rawlist)):
+
+			#if alloptions flag is on, apply to all plots
+			if (allflag and 'data' not in rawlist[i][0] and '#' not in rawlist[i][0]):
+				
+				for j in xrange(numberofplots):
+					self.list[j].addfield(rawlist[i][0],rawlist[i][1])
+
+			elif '#' in rawlist[i][0]:
+
+				#get subplots associated
+				string=rawlist[i][0].split('#')
+				plotnums=string[-1].split(',')
+				field=string[0]
+
+				#loop over plotnums
+				for k in xrange(len(plotnums)):
+					plotnum=plotnums[k]
+
+					#Empty
+					if not plotnum: continue
+
+					elif 'all' in plotnum:
+						for j in xrange(numberofplots):
+							self.list[j].addfield(field,rawlist[i][1])
+
+					elif '-' in plotnum:
+						nums=plotnum.split('-')
+						if len(nums)!=2: continue
+						if False in [x.isdigit() for x in nums]:
+							raise ValueError('error: in option i-j both i and j must be integers')
+						for j in xrange(int(nums[0])-1,int(nums[1])):
+							self.list[j].addfield(field,rawlist[i][1])	
+
+					# Deal with #i
+					else:
+						#assign to subplot
+						if int(plotnum)>numberofplots:
+							raise ValueError('error: %s cannot be assigned %d which exceeds the number of subplots' % (field,plotnum))
+						self.list[int(plotnum)-1].addfield(field,rawlist[i][1])
+			else:
+				
+				#go through all subplots and assign key-value pairs
+				j=0
+				while j <= numberofplots-1:
+					if not self.list[j].exist(rawlist[i][0]):
+						self.list[j].addfield(rawlist[i][0],rawlist[i][1])
+						break
+					else:
+						j=j+1
+				if j+1>numberofplots:
+					print "WARNING: too many instances of '%s' in options" % rawlist[i][0]
+	#}}}
Index: /issm/trunk-jpl/src/m/plot/checkplotoptions.py
===================================================================
--- /issm/trunk-jpl/src/m/plot/checkplotoptions.py	(revision 13411)
+++ /issm/trunk-jpl/src/m/plot/checkplotoptions.py	(revision 13411)
@@ -0,0 +1,15 @@
+def checkplotoptions(md,options):
+	'''
+	CHECKPLOTOPTIONS - build a structure that holds all plot options
+
+		Usage:
+			options=checkplotoptions(md,options)
+
+		See also: PLOTMODEL
+
+		NOTE: not fully implemented yet
+	'''
+
+	print "WARNING: checkplotoptions not implemented: options returned as passed"
+	return options
+
Index: /issm/trunk-jpl/src/m/plot/plot_manager.py
===================================================================
--- /issm/trunk-jpl/src/m/plot/plot_manager.py	(revision 13411)
+++ /issm/trunk-jpl/src/m/plot/plot_manager.py	(revision 13411)
@@ -0,0 +1,32 @@
+from pairoptions import *
+import pylab as p
+from checkplotoptions import *
+from plot_mesh import *
+
+def plot_manager(md,options,subplotwidth,nlines,ncols,i):
+	'''
+	PLOT_MANAGER - distribute the plots called by plotmodel
+
+		Usage:
+			plot_manager(md,options,subplotwidth,i);
+
+		See also: PLOTMODEL, PLOT_UNIT
+	'''
+
+	#parse options and get a structure of options
+	options=checkplotoptions(md,options)
+	#print 'options:', options
+
+	#get data to be plotted
+	data=options.getfieldvalue('data');
+
+	#figure out if this is a special plot
+	if isinstance(data,(str,unicode)):
+
+		if data=='mesh': plot_mesh(md,options,nlines,ncols,i)
+		else:
+			print "WARNING: '%s' is not implemented or is not a valid string for option 'data'" % data
+
+	else:
+		print "'data' not a string, plotting model properties yet to be implemented..."
+
Index: /issm/trunk-jpl/src/m/plot/plot_mesh.py
===================================================================
--- /issm/trunk-jpl/src/m/plot/plot_mesh.py	(revision 13411)
+++ /issm/trunk-jpl/src/m/plot/plot_mesh.py	(revision 13411)
@@ -0,0 +1,24 @@
+import pylab as p
+import matplotlib.tri as tri
+
+def plot_mesh(md,options,nlines,ncols,i):
+	'''
+	PLOT_MESH - plot model mesh
+
+		Usage:
+			plot_mesh(md,options,nlines,ncols,i)
+
+		See also: PLOTMODEL
+	'''
+
+	#TODO: implement processmesh
+	x=md.mesh.x
+	y=md.mesh.y
+	elements=md.mesh.elements
+	elements=elements-1 #since python indexes from zero
+
+	p.subplot(nlines,ncols,i)
+	p.triplot(x,y,elements)
+	p.title('Mesh')
+	
+	print 'WARNING: options passed to plot_mesh not implemented yet'
Index: /issm/trunk-jpl/src/m/plot/plotmodel.py
===================================================================
--- /issm/trunk-jpl/src/m/plot/plotmodel.py	(revision 13411)
+++ /issm/trunk-jpl/src/m/plot/plotmodel.py	(revision 13411)
@@ -0,0 +1,55 @@
+import pylab as p
+#from pairoptions import *
+from plotoptions import *
+from plot_manager import *
+
+def plotmodel(md,*args):
+	'''
+	at command prompt, type 'plotdoc' for additional documentation
+	'''
+
+	#First process options 
+	options=plotoptions(*args)
+
+	#get number of subplots
+	subplotwidth=math.ceil(math.sqrt(options.numberofplots))
+	
+	#if nlines and ncols specified, then bypass
+	if options.list[0].exist('nlines'):
+		nlines=options.list[0].getfieldvalue('nlines')
+		nl=True
+	else:
+		nlines=subplotwidth
+		nl=False
+	
+	if options.list[0].exist('ncols'):
+		ncols=options.list[0].getfieldvalue('ncols')
+		nc=True
+	else:
+		ncols=subplotwidth
+		nc=False
+	
+	#check that nlines and ncols were given at the same time!
+	if not nl==nc:
+		raise StandardError('error: nlines and ncols need to be specified together, or not at all')
+	
+	#Get figure number and number of plots
+	figurenumber=options.figurenumber
+	numberofplots=options.numberofplots
+	
+	#Go through plots
+	if numberofplots:
+	
+		#Create figure
+		#plots will be visible by default if ipython is run in interactive mode (invoked by ipython --pylab)
+		#handling the 'visible' option will need some check on whether ipython is currently in interactive or non-interactive mode
+		p.figure(figurenumber)
+	
+		try:
+			for i in xrange(numberofplots):
+				plot_manager(options.list[i].getfieldvalue('model',md),options.list[i],subplotwidth,nlines,ncols,i)
+		except StandardError:
+			print 'error in plot_manager'
+	else:
+		raise StandardError('plotmodel error message: no output data found.')
+			
