MathGroup Archive 1992

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: rescalling(sp)

  • To: mathgroup at yoda.physics.unc.edu
  • Subject: Re: rescalling(sp)
  • From: John Lee <lee at math.washington.edu>
  • Date: Fri, 6 Nov 92 10:44:36 -0800

Sherman C. Reed (reed at ee.uta.edu) writes:

> I need to know how to make the x and y axis on the printed copy
> be equal to the units specified.  Specifically a "1" on the x axis
> should be equal to "1" inch or "1" meter or whatever.  
> I know how to rescale the plot but I do not know the point values of the 
> extra spaacing due to the y axis and space at the end of the x axis.
> This is probably a medium problem, but it helps an optics person
> use Mma to teach design.


I had to confront this problem last year when teaching a calculus course in
which I wanted to give my students graphs drawn to an accurate scale.
Here's my solution.

I've written a function called ShowScaled, which behaves essentially the
same as Show, except that it accepts an additional argument, Scale -> n,
which specifies that the plot is to be scaled so that the entire plot area
is n units by n units (i.e. one unit on either axis corresponds to exactly
1/n of the total width of the graph).  The default is Scale -> 10.

The basic idea behind this solution is that, unlike axis labels and titles,
graphics primitives plotted by Prolog or Epilog do not affect where the
graph appears in the final output.  So ShowScaled takes the given graphics
object, and uses FullGraphics to turn it into a list of graphics
primitives.  It then plots a blank rectangle of the right size and scale to
establish the position of the coordinates on the plot, and superimposes the
list of primitives on that rectangle using Epilog.

There are two limitations to this code as it stands, due to bugs in
Mathematica 2.0 graphics.  (I don't know whether these are fixed in later
versions.)  First, if your graphics object contains a "PlotLabel" option,
the label will disappear when displayed by ShowScaled.  This is because
FullOptions apparently throws away the PlotLabel.  The code below could be
modified to pull out the PlotLabel option of "plot" and then put it back in
as an argument to Show in the last statement, but you would have to do some
fussing around to figure out where to position it; I didn't have the time
to do it.

Second, I would like to allow the Scale argument to specify the x and y
scales separately.  This would require using the AspectRatio option to
rescale the axes in the final plot.  However, there seems to be a bug in
the way AspectRatio interacts with PlotRange; whenever I specify an
explicit AspectRatio, the whole plot is scaled down to less than half the
size it's supposed to be.

I'd be interested in any comments or suggestions for improvements.

Jack Lee
Dept. of Mathematics
University of Washington

=========================================================================

(* Here's the code *)

ShowScaled::usage = "ShowScaled[graphics, options, Scale -> n] displays a
2-dimensional graphics object, scaled so that one unit occupies exactly
1/n of the total width of the graph.  It accepts the same options as Show.";

ShowScaled[args__] :=
  Module[{scaleargs,nonscaleargs,plot,xmin,xmax,
          ymin,ymax,gr,xcenter,ycenter,scale},

  (* first pull out the Scale option from args for later use. Default=10. *)

  scaleargs = If [!MemberQ[{args},Scale->_], 
                   {Null},
                   Options[{args}, Scale]
                 ];

  (* nonscaleargs = all the rest of the arguments.  
     Show doesn't want to see Scale. *)

  nonscaleargs = Complement[ {args}, scaleargs ];

  (* Now create a graphics object containing all the user's options *)

  plot = Show @@ Join[ nonscaleargs, 
                       {DisplayFunction -> Identity} ];

  (* Pull out the limits of data that was actually plotted,
     and find the center of the plot *)

  {{xmin,xmax},{ymin,ymax}} = FullOptions[plot,PlotRange][[{1,2}]];

  (* Now turn the graphics object into a list of graphics primitives *)

  gr = List @@ FullGraphics[ plot ];
  xcenter = (xmax+xmin)/2;
  ycenter = (ymax+ymin)/2;
  scale = If[ scaleargs === {Null},
              10,
              scaleargs[[1,2]]
            ];

  (* Finally, display the scaled plot. *)

  Show[ Graphics[{}],
        PlotRange -> {{xcenter - scale/2, xcenter + scale/2},
                      {ycenter - scale/2, ycenter + scale/2}},
        AspectRatio -> Automatic,
        Axes -> False,
        Epilog -> gr,
        DisplayFunction -> $DisplayFunction
      ]
  ];





  • Prev by Date: Conversion to Tex
  • Next by Date: StartUp`Elliptic` fix
  • Previous by thread: rescalling(sp)
  • Next by thread: Re: rescalling(sp)