419419long as the object exists, the plot will be interactive. Calling 'g.plot()'
420420multiple times reuses the plot window instead of creating a new one.
421421
422- ** global plot()
422+ ** global plot(... )
423423
424424The convenience plotting routine in gnuplotlib. Invocation:
425425
430430
431431Each 'plot()' call reuses the same window.
432432
433- ** plot3d
433+ ** global plot3d(...)
434434
435435Generates 3D plots. Shorthand for 'plot(..., _3d=True)'
436436
600600
601601* COMPATIBILITY
602602
603+ Only python 2 is supported. I have no plans to support python 3 (forcing me to
604+ care about unicode is stupid), but patches are welcome.
605+
603606Everything should work on all platforms that support Gnuplot and Python. That
604607said, only Debian GNU/Linux has been tested at this point. Comments and/or
605608patches are welcome.
621624published by the Free Software Foundation
622625
623626See https://www.gnu.org/licenses/lgpl.html
627+
624628'''
625629
626630
@@ -708,7 +712,7 @@ def _dictDeUnderscore(d):
708712 """
709713 d2 = {}
710714 for key in d :
711- if type (key ) is str and key [0 ] == '_' :
715+ if isinstance (key , ( str , bytes )) and key [0 ] == '_' :
712716 d2 [key [1 :]] = d [key ]
713717 else :
714718 d2 [key ] = d [key ]
@@ -735,8 +739,9 @@ def __init__(self, **plotOptions):
735739 self .plotOptions = _dictDeUnderscore (plotOptions )
736740 self .t0 = time .time ()
737741 self .checkpoint_stuck = False
742+ self .sync_count = 1
738743
739- plotOptionsCmd = self ._getPlotOptionsCmd ()
744+ plotOptionsCmds = self ._getPlotOptionsCmds ()
740745
741746 # if we already have a gnuplot process, reset it. Otherwise make a new
742747 # one
@@ -748,7 +753,7 @@ def __init__(self, **plotOptions):
748753 self ._startgnuplot ()
749754 self ._logEvent ("_startgnuplot() finished" )
750755
751- self ._safelyWriteToPipe (plotOptionsCmd )
756+ self ._safelyWriteToPipe (plotOptionsCmds )
752757
753758
754759 def _startgnuplot (self ):
@@ -768,7 +773,7 @@ def _startgnuplot(self):
768773 self ._safelyWriteToPipe ("set terminal push" , 'terminal' )
769774
770775
771- def _getPlotOptionsCmd (self ):
776+ def _getPlotOptionsCmds (self ):
772777
773778 def have (opt ): return self ._havePlotOption (opt )
774779 def active (opt ): return self ._activePlotOption (opt )
@@ -802,15 +807,15 @@ def active(opt): return self._activePlotOption(opt)
802807
803808
804809 # grid on by default
805- cmd = 'set grid\n '
810+ cmds = [ 'set grid' ]
806811
807812 # send all set/unset as is
808813 for setunset in ('set' , 'unset' ):
809814 if have (setunset ):
810- if type (self .plotOptions [setunset ]) is str :
811- self . plotOptions [ setunset ] = ( self .plotOptions [setunset ],)
812- for setting in self . plotOptions [ setunset ] :
813- cmd += setunset + ' ' + setting + ' \n '
815+ if isinstance (self .plotOptions [setunset ], ( list , tuple )) :
816+ cmds += [ setunset + ' ' + setting for setting in self .plotOptions [setunset ] ]
817+ else :
818+ cmds . append ( setunset + ' ' + self . plotOptions [ setunset ])
814819
815820 # set the plot bounds
816821
@@ -847,33 +852,33 @@ def active(opt): return self._activePlotOption(opt)
847852 rangeopt_val = self .plotOptions [rangeopt_name ]
848853 else :
849854 rangeopt_val = ''
850- cmd += "set {} [{}] {}\n " .format (rangeopt_name ,
851- rangeopt_val ,
852- 'reverse' if active (axis + 'inv' ) else '' )
855+ cmds . append ( "set {} [{}] {}" .format (rangeopt_name ,
856+ rangeopt_val ,
857+ 'reverse' if active (axis + 'inv' ) else '' ) )
853858
854859 # set the curve labels
855860 if not axis == 'cb' :
856861 if have (axis + 'label' ):
857- cmd += 'set {axis}label "{label}"\n ' .format (axis = axis ,
858- label = self .plotOptions [axis + 'label' ])
862+ cmds . append ( 'set {axis}label "{label}"' .format (axis = axis ,
863+ label = self .plotOptions [axis + 'label' ]) )
859864
860865
861866
862867 # set the title
863868 if have ('title' ):
864- cmd += 'set title "{}" \n ' . format ( self .plotOptions ['title' ])
869+ cmds . append ( 'set title "' + self .plotOptions ['title' ] + '"' )
865870
866871
867872 # handle a requested square aspect ratio
868873 # set a square aspect ratio. Gnuplot does this differently for 2D and 3D plots
869874 if active ('3d' ):
870875 if active ('square' ):
871- cmd += "set view equal xyz\n "
876+ cmds . append ( "set view equal xyz" )
872877 elif active ('square_xy' ):
873- cmd += "set view equal xy\n "
878+ cmds . append ( "set view equal xy" )
874879 else :
875880 if active ('square' ):
876- cmd += "set size ratio -1\n "
881+ cmds . append ( "set size ratio -1" )
877882
878883 # handle 'hardcopy'. This simply ties in to 'output' and 'terminal', handled
879884 # later
@@ -909,13 +914,12 @@ def active(opt): return self._activePlotOption(opt)
909914 if have ('cmds' ):
910915 # if there's a single cmds option, put it into a 1-element list to
911916 # make the processing work
912- if type (self .plotOptions ['cmds' ]) is str :
913- self .plotOptions ['cmds' ] = [self .plotOptions ['cmds' ]]
914-
915- for extracmd in self .plotOptions ['cmds' ]:
916- cmd += extracmd + "\n "
917+ if isinstance (self .plotOptions ['cmds' ], (list , tuple )):
918+ cmds += self .plotOptions ['cmds' ]
919+ else :
920+ cmds .append (self .plotOptions ['cmds' ])
917921
918- return cmd
922+ return cmds
919923
920924
921925
@@ -936,7 +940,7 @@ def __del__(self):
936940
937941
938942
939- def _safelyWriteToPipe (self , string , flags = '' ):
943+ def _safelyWriteToPipe (self , input , flags = '' ):
940944
941945 def barfOnDisallowedCommands (line ):
942946 # I use STDERR as the backchannel, so I don't allow any "set print"
@@ -969,18 +973,17 @@ def barfOnDisallowedCommands(line):
969973
970974
971975
972- for line in string .splitlines ():
973- line = line .strip ()
974- if not line :
975- continue
976+ if not isinstance (input , (list ,tuple )):
977+ input = (input ,)
976978
977- barfOnDisallowedCommands (line )
979+ for cmd in input :
980+ barfOnDisallowedCommands (cmd )
978981
979- self ._printGnuplotPipe ( line + '\n ' )
982+ self ._printGnuplotPipe ( cmd + '\n ' )
980983
981984 errorMessage , warnings = self ._checkpoint ('printwarnings' )
982985 if errorMessage :
983- barfmsg = "Gnuplot error: '\n {}\n ' while sending line '{}'\n " .format (errorMessage , line )
986+ barfmsg = "Gnuplot error: '\n {}\n ' while sending cmd '{}'\n " .format (errorMessage , cmd )
984987 if warnings :
985988 barfmsg += "Warnings:\n " + str (warnings )
986989 raise GnuplotlibError (barfmsg )
@@ -1002,7 +1005,13 @@ def _printGnuplotPipe(self, string):
10021005 # I test the plot command by making a dummy plot with the test command.
10031006 def _testPlotcmd (self , cmd , data ):
10041007
1005- self ._printGnuplotPipe ( "set output\n " )
1008+ # I don't actually want to see the plot, I just want to make sure that
1009+ # no errors are thrown. I thus send the output to /dev/null. Note that I
1010+ # never actually read stdout, so if this test plot goes to the default
1011+ # stdout output, then eventually the buffer fills up and gnuplot blocks.
1012+ # So keep it going to /dev/null, or make sure to read the test plot from
1013+ # stdout
1014+ self ._printGnuplotPipe ( "set output '/dev/null'\n " )
10061015 self ._printGnuplotPipe ( "set terminal dumb\n " )
10071016
10081017 # I send a test plot command. Gnuplot implicitly uses && if multiple
@@ -1032,7 +1041,8 @@ def _checkpoint(self, flags=''):
10321041 # yet arrived. I thus print out a checkpoint message and keep reading the
10331042 # child's STDERR pipe until I get that message back. Any errors would have
10341043 # been printed before this
1035- checkpoint = "xxxxxxx Syncronizing gnuplot i/o xxxxxxx"
1044+ checkpoint = "gpsync{}xxx" .format (self .sync_count )
1045+ self .sync_count += 1
10361046
10371047 self ._printGnuplotPipe ( 'print "{}"\n ' .format (checkpoint ) )
10381048
@@ -1141,7 +1151,7 @@ def _checkpoint(self, flags=''):
11411151 def _logEvent (self , event ):
11421152
11431153 # only log when asked
1144- if not 'log' in self . plotOptions :
1154+ if not self . _activePlotOption ( 'log' ) :
11451155 return
11461156
11471157 t = time .time () - self .t0
@@ -1435,13 +1445,13 @@ def plot(self, *curves, **curveOptions_base):
14351445 self ._safelyWriteToPipe ("set terminal pop; set terminal push" , 'terminal' )
14361446
14371447 if self ._havePlotOption ('terminal' ):
1438- self ._safelyWriteToPipe ("set terminal {} \n " . format ( self .plotOptions ['terminal' ]) ,
1448+ self ._safelyWriteToPipe ("set terminal " + self .plotOptions ['terminal' ],
14391449 'terminal' )
14401450
14411451 if self ._havePlotOption ('output' ):
14421452 if hasattr (self ,'fdDupSTDOUT' ) and self .plotOptions ['output' ] == '*STDOUT' :
14431453 self .plotOptions ['output' ] = '/dev/fd/' + str (self .fdDupSTDOUT )
1444- self ._safelyWriteToPipe ('set output "{}" \n ' . format ( self .plotOptions ['output' ]) ,
1454+ self ._safelyWriteToPipe ('set output "' + self .plotOptions ['output' ] + '"' ,
14451455 'output' )
14461456
14471457 # all done. make the plot
0 commit comments