login  home  contents  what's new  discussion  bug reports     help  links  subscribe  changes  refresh  edit

Edit detail for OldGnuDraw revision 1 of 2

1 2
Editor: Bill Page
Time: 2014/09/05 21:54:14 GMT+0
Note: work around problem with displaying the graphic

changed:
-
**Demonstrate how graphs may be plotted and displayed from !MathAction**

By: David Cyganski,  Tue, Jul 24, 2007 at 8:16 AM.

I have written an External Method that can be called from a !MathAction
web page to generate graphics that can be displayed on the page that created
them. The "gnupyplot" External Method uses a python script to call gnuplot to generate
2D and 3D graphics.  The link between !MathAction and gnupyplot is the same
!LocalFS "images" filesystem used by !MathAction which is found in the
!var/LatexWiki subdirectory of the zope instance.

The demonstration below is still "unpackaged" and needs to be pulled
into the form of a few more flexible functions, but the utility is fairly obvious
at this stage.  This packaging would involve setting it up to pass
one or more functions in a single call for plotting, choosing colors
for each, which can be done with some careful "map" crafting and function
overloading.

The "gnuplot" function samples a given expression over a given
range of values and writes the results into a file (with the
name testfile2.dat in the following example). We will have to use 
!DoubleFloats (for speed) expressed as text floats (for compatibility with gnuplot).
The format and method of getting there is the result of a great deal of
hacking and experimenting due to many non-obvious limitations, defaults
and assorted odd behaviors on Axiom's part when it comes to the treatment
of doubles as strings and the saving of text to text files!

The expression argument for gnuplot can be any expression in any single variable.
The variable name is declared as part of the range argument which takes a form
such as x=0..50 if we wish to plot some expression in x over 0 to 50.

\begin{axiom}
gnuplot(f,segbind,filename)==
  --Define number of function points to evaluate
  xpoints:=300
  xlo:=lo(segment(segbind))
  xhi:=hi(segment(segbind))
  xrange:DoubleFloat:=xhi-xlo
  xvar:=variable(segbind)
  dx:DoubleFloat:=xrange/(xpoints-1)
  --outputFloating(5)
  --outputSpacing(0)
  f1:TextFile:=open(filename,"output")
  for xindex in 0..(xpoints-1) repeat
    writeLine!(f1,concat( [unparse((xindex*dx)::InputForm)," ", _
                           unparse(eval(f, xvar=xindex*dx+xlo)::InputForm)]) ) 
  close! f1
\end{axiom}

\begin{axiom}
gnuplot(sin(z),z=0..30,"testfile2.dat")
\end{axiom}

<a href="http://axiom-wiki.newsynthesis.org/uploads/gnupyplot3.py.txt">gnupyplot3.py.txt</a>

*On Tue, Jun 24, 2008 at 8:16 PM Bill Page wrote:*

Instead of using the original external script, I have installed 
"gnuplot":http://www.gnuplot.info and
"gnuplottex":http://www.ctan.org/tex-archive/help/Catalogue/entries/gnuplottex.html
to permit gnuplot commands to be embedded in wiki pages using::

  !\begin{gnuplot}
  ...
  \end{gnuplot}

Here are some "good examples":http://www.gnuplot.info/demo of gnuplot scripts.

So now we can plot the data using the commands::

  !\begin{gnuplot}[terminal=pslatex,terminaloptions=color,scale=1.3]
  set title "sin(z),z=0..30"
  plot "testfile2.dat" title "" with lines
  \end{gnuplot}

<center>
!\begin{gnuplot}[terminal=pslatex,terminaloptions=color,scale=1.3]
set title "sin(z),z=0..30"
plot "testfile2.dat" title "" with lines
!\end{gnuplot}
</center>

By changing a single statement in the gnupyplot function we can have the image
display in an Xwindow, hence one can easily use the same code but for this one
parametric change for both interactive and !MathAction application.

Of course this can also be done directly using just gnuplot::

  !\begin{gnuplot}[terminal=pslatex,terminaloptions=color,scale=1.3]
  plot [z=0:30] [-1.0:1.0] sin(z) title "" with lines
  \end{gnuplot}

<center>
!\begin{gnuplot}[terminal=pslatex,terminaloptions=color,scale=1.3]
plot [z=0:30] [-1.0:1.0] sin(z) title "" with lines
!\end{gnuplot}
</center>

I would like to add the ability to handle lists of functions by overloading gnuplot
to accept the single expression or a list. Simpling writing the additional values
for each curve successively onto the same line of the data file will allow
gnupyplot to generate such plots. Only a minor change needs to be made
to gnupyplot to support this generality.

One could also use a similar approach to directly display !MathAction draw
function graphs. What we have to do is write a string file output function
that reads the format of the "vp" port data generated by Axiom and convert
it to the simple textfile, one point per line, style needed by gnuplot.

In order to take advantage of function name overloading it is desirable to
write this code in SPAD. That allows us to call 'gnuDraw' in much the same
way as we would call 'draw' in Axiom. This routine uses 'draw' internally
to create the plot data structure.

\begin{spad}
)abbrev package GDRAW GnuDraw
++ Author: Bill Page and David Cyganski
++ Date: June 25, 2008
++ Description:
++ This package provides support for gnuplot. These routines
++ generate output files contain gnuplot scripts that may be
++ processed directly by gnuplot. This is especially convenient
++ in the axiom-wiki environment where gnuplot is called from
++ LaTeX via gnuplottex.

EF ==> Expression Float
SBF ==> SegmentBinding Float
DROP ==> DrawOption
DROP0 ==> DrawOptionFunctions0
STR ==> String
LDF ==> List DoubleFloat
GnuDraw(): with
  gnuDraw:(EF, SBF, STR, List DROP)->Void
  ++ \spad{gnuDraw} provides 2d plotting with options
  gnuDraw:(LDF,LDF, STR, List DROP)->Void
  ++ \spad{gnuDraw} provides 2d plotting from list of values with options
  gnuDraw:(EF, SBF, STR)->Void
  ++ \spad{gnuDraw} provides 2d plotting, default options
  gnuDraw:(LDF,LDF, STR)->Void
  ++ \spad{gnuDraw} provides 2d plotting from list of values, default options
  gnuDraw:(EF, SBF, SBF, STR, List DROP)->Void
  ++ \spad{gnuDraw} provides 3d surface plotting with options
  gnuDraw:(EF, SBF, SBF, STR)->Void
  ++ \spad{gnuDraw} provides 3d surface plotting, default options
 == add
  -- 2-d plotting
  gnuDraw(f:EF,segbind:SBF,filename:STR,opts:List DROP):Void ==
    import TwoDimensionalViewport, GraphImage, TopLevelDrawFunctions EF
    f1:TextFile:=open(filename::FileName,"output")
    -- handle optional parameters
    writeLine!(f1,concat(["set title _"",title(opts,"")$DROP0,"_""]))
    writeLine!(f1,"plot '-' title '' lw 3 with lines")
    -- extract data as List List Point DoubleFloat
    p2:=pointLists(getGraph(draw(f, segbind),1));
    for p1 in p2 repeat
      for p in p1 repeat
        writeLine!(f1,concat([unparse(convert(p.1)@InputForm)," ",
                              unparse(convert(p.2)@InputForm)]))
      writeLine!(f1); -- blank line need to mark a "branch"
    close! f1
  gnuDraw(l1:LDF,l2:LDF,filename:STR,opts:List DROP):Void ==
    import TwoDimensionalViewport, GraphImage, TopLevelDrawFunctionsForPoints
    f1:TextFile:=open(filename::FileName,"output")
    -- handle optional parameters
    writeLine!(f1,concat(["set title _"",title(opts,"")$DROP0,"_""]))
    writeLine!(f1,"plot '-' title '' lw 3 with lines")
    -- extract data as List List Point DoubleFloat
    p2:=pointLists(getGraph(draw(l1, l2),1));
    for p1 in p2 repeat
      for p in p1 repeat
        writeLine!(f1,concat([unparse(convert(p.1)@InputForm)," ",
                              unparse(convert(p.2)@InputForm)]))
      writeLine!(f1); -- blank line need to mark a "branch"
    close! f1
  -- default title is ""
  gnuDraw(f:EF,segbind:SBF,filename:STR):Void ==
    gnuDraw(f,segbind,filename,[title("")$DROP])
  gnuDraw(l1:LDF,l2:LDF,filename:STR):Void ==
    gnuDraw(l1,l2,filename,[title("")$DROP])

  -- 3-d plotting
  gnuDraw(f:EF,segbind1:SBF, segbind2:SBF, filename:STR, opts:List DROP):Void ==
    import SubSpace, ThreeSpace DoubleFloat, TopLevelDrawFunctions EF
    f1:TextFile:=open(filename::FileName,"output")
    -- process optional parameters
    writeLine!(f1,concat(["set title _"",title(opts,"")$DROP0,"_""]))
    writeLine!(f1,"splot '-' title '' with pm3d")
    -- extract data as List List Point DoubleFloat
    p2:=mesh(subspace(draw(f, segbind1, segbind2)));
    for p1 in p2 repeat
      for p in p1 repeat
        writeLine!(f1,concat([unparse(convert(p.1)@InputForm)," ",
                              unparse(convert(p.2)@InputForm)," ",
                              unparse(convert(p.3)@InputForm)]))
      writeLine!(f1); -- blank line need to mark a "branch"
    close! f1
  -- default title is ""
  gnuDraw(f:EF,segbind1:SBF, segbind2:SBF, filename:STR):Void ==
    gnuDraw(f,segbind1,segbind2,filename,[title("")$DROP])
\end{spad}

\begin{axiom}
D(cos(exp(z))/exp(z^2),z)
gnuDraw(%,z=-5..5,"testfile1.dat",title=="fun2")
\end{axiom}

<center>
!\begin{gnuplot}[terminal=pslatex,terminaloptions=color,scale=1.3]
load "testfile1.dat"
!\end{gnuplot}
</center>

\begin{axiom}
gnuDraw(sin(x)*cos(y),x=-6..4,y=-4..6,"testfile4.dat",title=="fun3")
\end{axiom}

From MartinBaker Sat Jun 12 09:03:55 -0700 2010
From: Martin Baker
Date: Sat, 12 Jun 2010 09:03:55 -0700
Subject: GnuDraw bug
Message-ID: <20100612090355-0700@axiom-wiki.newsynthesis.org>

When I tried to compile GnuDraw in FriCAS 1.0.9 I found that this line produced an error

import SubSpace, ThreeSpace DoubleFloat, TopLevelDrawFunctions EF

It worked when I changed it to:

import SubSpace(3,DoubleFloat), ThreeSpace DoubleFloat, TopLevelDrawFunctions EF

otherwise I am finding this code very useful, thanks,
Martin Baker

<center>
\begin{gnuplot}[terminal=pslatex,terminaloptions=color,scale=1.3]
set parametric
set hidden
set view 60,55
set xlabel "x"
set ylabel "y"
set zrange [-1:1]
set mxtics
set pm3d depthorder
#set palette gray
load "testfile4.dat"
\end{gnuplot}
</center>



Demonstrate how graphs may be plotted and displayed from MathAction

By: David Cyganski, Tue, Jul 24, 2007 at 8:16 AM.

I have written an External Method that can be called from a MathAction web page to generate graphics that can be displayed on the page that created them. The "gnupyplot" External Method uses a python script to call gnuplot to generate 2D and 3D graphics. The link between MathAction and gnupyplot is the same LocalFS "images" filesystem used by MathAction which is found in the var/LatexWiki subdirectory of the zope instance.

The demonstration below is still "unpackaged" and needs to be pulled into the form of a few more flexible functions, but the utility is fairly obvious at this stage. This packaging would involve setting it up to pass one or more functions in a single call for plotting, choosing colors for each, which can be done with some careful "map" crafting and function overloading.

The "gnuplot" function samples a given expression over a given range of values and writes the results into a file (with the name testfile2.dat in the following example). We will have to use DoubleFloats (for speed) expressed as text floats (for compatibility with gnuplot). The format and method of getting there is the result of a great deal of hacking and experimenting due to many non-obvious limitations, defaults and assorted odd behaviors on Axiom's part when it comes to the treatment of doubles as strings and the saving of text to text files!

The expression argument for gnuplot can be any expression in any single variable. The variable name is declared as part of the range argument which takes a form such as x=0..50 if we wish to plot some expression in x over 0 to 50.

fricas
gnuplot(f,segbind,filename)==
  --Define number of function points to evaluate
  xpoints:=300
  xlo:=lo(segment(segbind))
  xhi:=hi(segment(segbind))
  xrange:DoubleFloat:=xhi-xlo
  xvar:=variable(segbind)
  dx:DoubleFloat:=xrange/(xpoints-1)
  --outputFloating(5)
  --outputSpacing(0)
  f1:TextFile:=open(filename,"output")
  for xindex in 0..(xpoints-1) repeat
    writeLine!(f1,concat( [unparse((xindex*dx)::InputForm)," ", _
                           unparse(eval(f, xvar=xindex*dx+xlo)::InputForm)]) ) 
  close! f1
Type: Void

fricas
gnuplot(sin(z),z=0..30,"testfile2.dat")
fricas
Compiling function gnuplot with type (Expression(Integer),
      SegmentBinding(NonNegativeInteger),String) -> TextFile

\label{eq1}\mbox{\tt "testfile2.dat"}(1)
Type: TextFile?

gnupyplot3.py.txt

On Tue, Jun 24, 2008 at 8:16 PM Bill Page wrote:

Instead of using the original external script, I have installed gnuplot and gnuplottex to permit gnuplot commands to be embedded in wiki pages using:

  \begin{gnuplot}
  ...
  \end{gnuplot}

Here are some good examples of gnuplot scripts.

So now we can plot the data using the commands:

  \begin{gnuplot}[terminal=pslatex,terminaloptions=color,scale=1.3]
  set title "sin(z),z=0..30"
  plot "testfile2.dat" title "" with lines
  \end{gnuplot}

\begin{gnuplot}[terminal=pslatex,terminaloptions=color,scale=1.3]? set title "sin(z),z=0..30" plot "testfile2.dat" title "" with lines \end{gnuplot}

By changing a single statement in the gnupyplot function we can have the image display in an Xwindow, hence one can easily use the same code but for this one parametric change for both interactive and MathAction application.

Of course this can also be done directly using just gnuplot:

  \begin{gnuplot}[terminal=pslatex,terminaloptions=color,scale=1.3]
  plot [z=0:30] [-1.0:1.0] sin(z) title "" with lines
  \end{gnuplot}

\begin{gnuplot}[terminal=pslatex,terminaloptions=color,scale=1.3]? plot [z=0:30]? [-1.0:1.0]? sin(z) title "" with lines \end{gnuplot}

I would like to add the ability to handle lists of functions by overloading gnuplot to accept the single expression or a list. Simpling writing the additional values for each curve successively onto the same line of the data file will allow gnupyplot to generate such plots. Only a minor change needs to be made to gnupyplot to support this generality.

One could also use a similar approach to directly display MathAction draw function graphs. What we have to do is write a string file output function that reads the format of the "vp" port data generated by Axiom and convert it to the simple textfile, one point per line, style needed by gnuplot.

In order to take advantage of function name overloading it is desirable to write this code in SPAD. That allows us to call gnuDraw in much the same way as we would call draw in Axiom. This routine uses draw internally to create the plot data structure.

spad
)abbrev package GDRAW GnuDraw
++ Author: Bill Page and David Cyganski
++ Date: June 25, 2008
++ Description:
++ This package provides support for gnuplot. These routines
++ generate output files contain gnuplot scripts that may be
++ processed directly by gnuplot. This is especially convenient
++ in the axiom-wiki environment where gnuplot is called from
++ LaTeX via gnuplottex.
EF ==> Expression Float SBF ==> SegmentBinding Float DROP ==> DrawOption DROP0 ==> DrawOptionFunctions0 STR ==> String LDF ==> List DoubleFloat GnuDraw(): with gnuDraw:(EF, SBF, STR, List DROP)->Void ++ \spad{gnuDraw} provides 2d plotting with options gnuDraw:(LDF,LDF, STR, List DROP)->Void ++ \spad{gnuDraw} provides 2d plotting from list of values with options gnuDraw:(EF, SBF, STR)->Void ++ \spad{gnuDraw} provides 2d plotting, default options gnuDraw:(LDF,LDF, STR)->Void ++ \spad{gnuDraw} provides 2d plotting from list of values, default options gnuDraw:(EF, SBF, SBF, STR, List DROP)->Void ++ \spad{gnuDraw} provides 3d surface plotting with options gnuDraw:(EF, SBF, SBF, STR)->Void ++ \spad{gnuDraw} provides 3d surface plotting, default options == add -- 2-d plotting gnuDraw(f:EF,segbind:SBF,filename:STR,opts:List DROP):Void == import TwoDimensionalViewport, GraphImage, TopLevelDrawFunctions EF f1:TextFile:=open(filename::FileName,"output") -- handle optional parameters writeLine!(f1,concat(["set title _"",title(opts,"")$DROP0,"_""])) writeLine!(f1,"plot '-' title '' lw 3 with lines") -- extract data as List List Point DoubleFloat p2:=pointLists(getGraph(draw(f, segbind),1)); for p1 in p2 repeat for p in p1 repeat writeLine!(f1,concat([unparse(convert(p.1)@InputForm)," ", unparse(convert(p.2)@InputForm)])) writeLine!(f1); -- blank line need to mark a "branch" close! f1 gnuDraw(l1:LDF,l2:LDF,filename:STR,opts:List DROP):Void == import TwoDimensionalViewport, GraphImage, TopLevelDrawFunctionsForPoints f1:TextFile:=open(filename::FileName,"output") -- handle optional parameters writeLine!(f1,concat(["set title _"",title(opts,"")$DROP0,"_""])) writeLine!(f1,"plot '-' title '' lw 3 with lines") -- extract data as List List Point DoubleFloat p2:=pointLists(getGraph(draw(l1, l2),1)); for p1 in p2 repeat for p in p1 repeat writeLine!(f1,concat([unparse(convert(p.1)@InputForm)," ", unparse(convert(p.2)@InputForm)])) writeLine!(f1); -- blank line need to mark a "branch" close! f1 -- default title is "" gnuDraw(f:EF,segbind:SBF,filename:STR):Void == gnuDraw(f,segbind,filename,[title("")$DROP]) gnuDraw(l1:LDF,l2:LDF,filename:STR):Void == gnuDraw(l1,l2,filename,[title("")$DROP])
-- 3-d plotting gnuDraw(f:EF,segbind1:SBF, segbind2:SBF, filename:STR, opts:List DROP):Void == import SubSpace, ThreeSpace DoubleFloat, TopLevelDrawFunctions EF f1:TextFile:=open(filename::FileName,"output") -- process optional parameters writeLine!(f1,concat(["set title _"",title(opts,"")$DROP0,"_""])) writeLine!(f1,"splot '-' title '' with pm3d") -- extract data as List List Point DoubleFloat p2:=mesh(subspace(draw(f, segbind1, segbind2))); for p1 in p2 repeat for p in p1 repeat writeLine!(f1,concat([unparse(convert(p.1)@InputForm)," ", unparse(convert(p.2)@InputForm)," ", unparse(convert(p.3)@InputForm)])) writeLine!(f1); -- blank line need to mark a "branch" close! f1 -- default title is "" gnuDraw(f:EF,segbind1:SBF, segbind2:SBF, filename:STR):Void == gnuDraw(f,segbind1,segbind2,filename,[title("")$DROP])
spad
   Compiling FriCAS source code from file 
      /var/lib/zope2.10/instance/axiom-wiki/var/LatexWiki/7123067021529709258-25px003.spad
      using old system compiler.
   GDRAW abbreviates package GnuDraw 
------------------------------------------------------------------------
   initializing NRLIB GDRAW for GnuDraw 
   compiling into NRLIB GDRAW 
   compiling exported gnuDraw : (Expression Float,SegmentBinding Float,String,List DrawOption) -> Void
Time: 0.35 SEC.
compiling exported gnuDraw : (List DoubleFloat,List DoubleFloat,String,List DrawOption) -> Void Time: 0.04 SEC.
compiling exported gnuDraw : (Expression Float,SegmentBinding Float,String) -> Void Time: 0 SEC.
compiling exported gnuDraw : (List DoubleFloat,List DoubleFloat,String) -> Void Time: 0.01 SEC.
compiling exported gnuDraw : (Expression Float,SegmentBinding Float,SegmentBinding Float,String,List DrawOption) -> Void Time: 0.25 SEC.
compiling exported gnuDraw : (Expression Float,SegmentBinding Float,SegmentBinding Float,String) -> Void Time: 0 SEC.
(time taken in buildFunctor: 0)
;;; *** |GnuDraw| REDEFINED
;;; *** |GnuDraw| REDEFINED Time: 0 SEC.
Cumulative Statistics for Constructor GnuDraw Time: 0.65 seconds
finalizing NRLIB GDRAW Processing GnuDraw for Browser database: --------constructor--------- --------(gnuDraw ((Void) (Expression (Float)) (SegmentBinding (Float)) (String) (List (DrawOption))))--------- --------(gnuDraw ((Void) (List (DoubleFloat)) (List (DoubleFloat)) (String) (List (DrawOption))))--------- --------(gnuDraw ((Void) (Expression (Float)) (SegmentBinding (Float)) (String)))--------- --------(gnuDraw ((Void) (List (DoubleFloat)) (List (DoubleFloat)) (String)))--------- --------(gnuDraw ((Void) (Expression (Float)) (SegmentBinding (Float)) (SegmentBinding (Float)) (String) (List (DrawOption))))--------- --------(gnuDraw ((Void) (Expression (Float)) (SegmentBinding (Float)) (SegmentBinding (Float)) (String)))--------- ; compiling file "/var/aw/var/LatexWiki/GDRAW.NRLIB/GDRAW.lsp" (written 09 SEP 2014 11:48:18 AM):
; /var/aw/var/LatexWiki/GDRAW.NRLIB/GDRAW.fasl written ; compilation finished in 0:00:00.053 ------------------------------------------------------------------------ GnuDraw is now explicitly exposed in frame initial GnuDraw will be automatically loaded when needed from /var/aw/var/LatexWiki/GDRAW.NRLIB/GDRAW

fricas
D(cos(exp(z))/exp(z^2),z)

\label{eq2}{-{{{e}^{z}}\ {\sin \left({{e}^{z}}\right)}}-{2 \  z \ {\cos \left({{e}^{z}}\right)}}}\over{{e}^{{z}^{2}}}(2)
Type: Expression(Integer)
fricas
gnuDraw(%,z=-5..5,"testfile1.dat",title=="fun2")
fricas
Compiling function %C with type DoubleFloat -> DoubleFloat 
   Graph data being transmitted to the viewport manager...
   FriCAS2D data being transmitted to the viewport manager...
Type: Void

\begin{gnuplot}[terminal=pslatex,terminaloptions=color,scale=1.3]? load "testfile1.dat" \end{gnuplot}

fricas
gnuDraw(sin(x)*cos(y),x=-6..4,y=-4..6,"testfile4.dat",title=="fun3")
fricas
Compiling function %E with type (DoubleFloat,DoubleFloat) -> 
      DoubleFloat 
   Transmitting data...
Type: Void

GnuDraw? bug --Martin Baker, Sat, 12 Jun 2010 09:03:55 -0700 reply
When I tried to compile GnuDraw? in FriCAS? 1.0.9 I found that this line produced an error

import SubSpace?, ThreeSpace? DoubleFloat?, TopLevelDrawFunctions? EF

It worked when I changed it to:

import SubSpace?(3,DoubleFloat?), ThreeSpace? DoubleFloat?, TopLevelDrawFunctions? EF

otherwise I am finding this code very useful, thanks, Martin Baker

[terminal=pslatex,terminaloptions=color,scale=1.3]
set parametric
set hidden
set view 60,55
set xlabel "x"
set ylabel "y"
set zrange [-1:1]
set mxtics
set pm3d depthorder
#set palette gray
load "testfile4.dat"