(*:Version: Mathematica 2.0 *)

(*:Name: Graphics`Graphics` *)

(*:Title: Additional Graphics Functions *)

(*:Author: Wolfram Research, Inc. *)

(*:History:
	Original Version by Wolfram Research, Inc.
	Revised by Michael Chan and Kevin McIsaac (Wolfram Research), 
	March, 1990.  Further revisions by Bruce Sawhill (Wolfram
	Research), Sept., 1990.
	Further revisions by ECM (Wolfram Research), Dec., 1990.
	Removal of 3D graphics functions to the package Graphics3D.m and
	minor revisions by John M. Novak, March, 1991.
*)

(*:Summary:
     Defines some functions to extend Mathematica's graphing capabilities.
*)

(*:Keywords:
	Log, Graphics, ListPlot, Scale, Polar
*)

(*:Requirements: None *)

(*:Warnings:
	Expands the definitions of PlotStyle.
*)

(*:Sources: *)

BeginPackage["Graphics`Graphics`"];

(* Usage messages *)

LinearScale::usage =
"LinearScale[xmin, xmax] gives a list of \"nice\" values between xmin and xmax

suitable for use as tick mark positions.  LinearScale[xmin, xmax, n] attempts
to find n such values.";

LogScale::usage =
"LogScale[xmin, xmax] gives a list of \"nice\" values between xmin and xmax
suitable for use as tick mark positions on a logarithmic scale.
LogScale[xmin, xmax, n] attempts to find n such values.";

UnitScale::usage =
"UnitScale[xmin, xmax, unit] gives a list of \"nice\" values between xmin and
xmax that are multiples of unit.  UnitScale[xmin, xmax, unit, n] attempts to
find n such values.";

PiScale::usage =
"PiScale[xmin, xmax] gives a list of \"nice\" values between xmin and xmax 
that
are multiples of Pi.  PiScale[xmin, xmax, n] attempts to find n such values.";


LogGridMinor::usage =
"LogGridMinor[xmin, xmax] gives a list of \"nice\" values between xmin and
xmax suitable for use as grid line positions on a logarithmic scale. The
positions are the same as those for major and minor tick marks from LogScale.
LogGridMinor[xmin, xmax, n] attempts to find n such values.";

LogGridMajor::usage =
"LogGridMajor[xmin, xmax] gives a list of \"nice\" values between xmin and
xmax suitable for use as grid line positions on a logarithmic scale. The
positions are the same as those for major tick marks from LogScale.
LogGridMajor[xmin, xmax, n] attempts to find n such values.";

TextListPlot::usage =
"TextListPlot[{y1, y2, ...}] plots a list, with each point {i,yi} rendered as
its index number i.  TextListPlot[{{x1,y1},{x2,y2}, ...}] renders the point
{xi,yi} as its index number i.  TextListPlot[{{x1, y1, t1}, {x2, y2, t2},
 ...}]
renders the point {xi,yi} as the text ti.";

LabeledListPlot::usage =
"LabeledListPlot[{y1, y2, ...}] plots a list, with each point {i,yi} labeled
with its index number i.  LabeledListPlot[{{x1,y1},{x2,y2}, ...}] labels the
point {xi,yi} with its index number i.  TextListPlot[{{x1, y1, t1},
{x2, y2, t2}, ...}] labels the point {xi,yi} with the text ti.";

LogPlot::usage =
"LogPlot[f, {x, xmin, xmax}] generates a plot of Log[f] as a function of x.";

LogListPlot::usage =
"LogListPlot[{y1, y2, ...}] or LogListPlot[{{x1, y1}, {x2, y2}, ...}] 
generates
a plot of Log[yi] against the xi.";

LogLogPlot::usage = 
"LogLogPlot[f, {x, xmin, xmax}] generates a plot of Log[f] as a function of
Log[x]." ;

BodeMagnitudePlot::usage = 
"BodePlot[f, {x, xmin, xmax}] generates a plot of 20*log[|f|] as a function of
Log[x]." ;

BodePhasePlot::usage = 
"BodePlot[f, {x, xmin, xmax}] generates a plot of Arg[f]*180/Pi as a function 
of Log[x]." ;

BodePhasePlot180::usage = 
"BodePlot[f, {x, xmin, xmax}] generates a plot of Arg[f]*180/Pi as a function 
of Log[x]." ;

LogLogListPlot::usage = 
"LogLogListPlot[{y1, y2, ...}] or LogLogListPlot[{{x1, y1}, {x2, y2}, ...}]
generates a plot of Log[yi] against Log[xi].";

PolarPlot::usage =
"PolarPlot[r, {t, tmin, tmax}] generates a polar plot of r as a function of t.

PolarPlot[{r1, r2, ...}, {t, tmin, tmax}] plots each of the ri as a function 
of
t on the same graph.";

PolarListPlot::usage =
"PolarListPlot[{r1, r2, ...}] generates a polar plot, assuming that the ri are

equally spaced in angle.";

ErrorListPlot::usage =
"ErrorListPlot[{{y1, dy1}, {y2, dy2}, ...}] plots a list of data with error
bars. ErrorListPlot[{{x1, y1, dy1}, ...}] allows x, as well as y, positions to

be specified.";

BarChart::usage =
"BarChart[{y1, y2, ...}] generates a bar chart of the values yi.  BarChart[{{
y1,
t1}, {y2, t2}, ...}] labels the i-th bar ti.  BarChart[{{y1, t1, s1},  
{y2, t2, s2},...}] labels the i-th bar ti and displays the bar with style si.
";

(* The option BarStyle specifies the default style for the bars.  BarSpacing
gives the fraction of the bar width to be allowed as separation between the 
bars.  BarEdges specifies whether edges are to be drawn around the bars.
BarEdgeStyle gives the style for the edges. BarOrientation can be either
Horizontal or Vertical to specify the orientation of the bars. *)

BarStyle::usage =
"BarStyle is an option for BarChart that determines the default style for the
bars.";

BarEdges::usage =
"BarEdges is an option for BarChart that determines whether edges are to be
drawn around the bars.";

BarEdgeStyle::usage =
"BarEdgeStyle is an option for BarChart that determines the style for the
edges.";

BarSpacing::usage =
"BarSpacing is an option for BarChart that determines the fraction of the
bar width to be allowed as separation between the bars.";

BarOrientation::usage =
"BarOrientation is an option for BarChart that determines whether the bars are

oriented vertically or horizontally.";

Vertical::usage = Horizontal::usage =
"Vertical and Horizontal are possible values for BarOrientation, an option of
BarChart.";

PieChart::usage =
"PieChart[{y1, y2, ...}] generates a pie chart of the values yi.
PieChart[{{y1, t1}, {y2, t2}, ...}] labels the i-th wedge ti. 
The values yi do not need to add up to 1.";

TransformGraphics::usage =
"TransformGraphics[graphics, f] applies the function f to all lists of
coordinates in graphics.";

SkewGraphics::usage =
"SkewGraphics[graphics, m] applies the matrix m to all coordinates in 
graphics.";

PlotStyle::usage =
"PlotStyle is an option for Plot and ListPlot that specifies the style of 
lines
or points to be plotted.  PlotStyle[graphics] will return the PlotStyle for
a graphic image created by Plot or ListPlot.";

Begin["`Private`"]

(* Define a better NumberQ *)

numberQ[x_] := NumberQ[N[x]]

(* PlotStyle *)

Unprotect[PlotStyle];

PlotStyle[Graphics[g:{{__,_List}..},opts___]] :=
  Map[PlotStyle[Graphics[#,opts]]&, g]

PlotStyle[Graphics[g_List,opts___]] := 
	Module[{q},
	 If[
	  Length[
	   q=Select[Drop[g,-1],
	             MemberQ[{RGBColor,GrayLevel,Thickness,Dashing,PointSize},
			     Head[#]]&
		   ]
		] > 1,
	   {q}, q]]
Protect[PlotStyle];


(* Linear Scale *)

LinearScale[min_, max_, n_Integer:8] :=
	Module[{spacing, t, nmin=N[min], nmax=N[max]},
		(spacing = TickSpacing[nmax-nmin, n, {1, 2, 2.5, 5, 10}] ;
		t = Range[Ceiling[nmin/spacing - 0.05] spacing, max, spacing] ;
		Map[{#, If[Round[#]==#, Round[#], #]}&, t])
	/; nmin < nmax
	]

TickSpacing[dx_, n_Integer, prefs_List] :=
	Module[ { dist=N[dx/n], scale } ,
		scale = 10.^Floor[Log[10., dist]] ;
		dist /= scale ;
		If[dist < 1, dist *= 10 ; scale /= 10] ;
		If[dist >= 10, dist /= 10 ; scale *= 10] ;
		scale * First[Select[prefs, (dist <= #)&]]
	]

(* LogScale *)

LogScale[min_, max_, n_Integer:6] :=
        Module[{pts} ,
		pts = GenGrid[ min, max, n] ;
		Join[ Map[ LogTicks, pts ], MinorLogTicks[pts]]
	] /; N[min] < N[max]

LogGridMajor[ min_, max_, n_Integer:6] :=
        Module[{pts} ,
                pts = GenGrid[ min, max, n] ; 
                Map[ Log[10, #]& , pts ]
        ] /; N[min] < N[max]

LogGridMinor[ min_, max_, n_Integer:6] :=
        Module[{pts} ,
                pts = GenGrid[ min, max, n] ; 
		Union[ Map[ Log[10., #]&,pts],
                       Map[ First, MinorLogTicks[pts]]]
        ] /; N[min] < N[max]

GenGrid[min_, max_, n_Integer:6] :=
        Module[{nmin=N[min], nmax=N[max], imin, imax, nper, t, tl} ,
                imin=Round[nmin] ;
                imax=Round[nmax] ;
                If[imin == imax, imax+=1];
                nper = Floor[n/(imax - imin)] ;
                If[nper > 0,
                        t = 10.^Range[imin, imax] ;
                        tl = Take[ $LogPreferances,
                                Min[nper, Length[$LogPreferances]] ] ;
                        t = Flatten[Outer[Times, t, tl]] ;
                        t = Sort[t] ,
                        (* else *)
                        nper = Ceiling[(imax - imin)/n] ;
                        t = 10.^Range[imin, imax, nper]
                ] ;
	t
        ]

LogTicks[x_] :=
	{Log[10., x],NumberForm[x]}

MinorLogTicks[pts_] :=
        Module[ {cd1=pts, cd2 },
                cd2 = Transpose[{ Drop[cd1, {1}],
                                     Drop[Map[ Minus, cd1], {-1}]}] ;
                cd2 = Apply[ Plus, cd2, 1] ;
                cd2 = Map[ MinorAux1, cd2] ;
                cd1 = Transpose[ { Drop[cd1, {-1}], cd2}] ;
                Flatten[ Map[ MinorAux2, cd1], 1]
        ]       
 
MinorAux2[{xst_, {del_ , n_}}] :=
        Module[{xfin = xst+del*(n-1),pts,x},
                pts = Table[x, {x, xst+del, xfin, del}] ;
                Map[ {Log[10., #], "", {0.6/160., 0.},
                                {Thickness[0.001]}}&, pts ]
        ]
 
MinorAux1[x_] :=
        Module[{n=Floor[ x/10^Floor[ Log[10., x]]]},
                If[ n < 1, {1,1}, {x/n, n}]
        ]

$LogPreferances = {1, 5, 2, 3, 1.5, 7, 4, 6, 1.2, 8, 9, 1.3, 2.5, 1.1, 1.4}
{1, 5, 2, 3, 1.5, 7, 4, 6, 1.2, 8, 9, 1.3, 2.5, 1.1, 1.4}

(* UnitScale *)

UnitScale[min_, max_, unit_, n_Integer:8] :=
	Module[{spacing, t,
		imin=Ceiling[N[min/unit]],imax = Floor[N[max/unit]]},
		(spacing = TickSpacing[imax-imin, n, {1, 2, 5, 10}] ;
		t = Range[Ceiling[imin/spacing - 0.05] spacing, imax,
				spacing] ;
		t = Union[Round[t]] ;
		Map[{N[# unit], # unit}&, t])
	/; N[min] < N[max]
	]

(* PiScale *)

PiScale[min_, max_, n_Integer:8] :=
	UnitScale[min, max, Pi/2, n] /; min < max

(* TextListPlot *)

TextListPlot[data:{_?numberQ ..}, opts___] :=
        TextListPlot[Transpose[{Range[Length[data]], 
					data, Range[Length[data]]}]]

TextListPlot[data:{{_?numberQ, _}..}, opts___] :=
        TextListPlot[Transpose[Join[Transpose[data], {Range[Length[data]]}]]]

TextListPlot[data:{{_?numberQ, _?numberQ, _}..}, opts___] :=
        Show[Graphics[ Text[Last[#], Take[#, 2]]& /@ data,
                        opts, Axes->Automatic]]

(* LabeledListPlot *)

LabeledListPlot[data:{_?numberQ ..}, opts___] :=
        LabeledListPlot[Transpose[{Range[Length[data]],
                                        data, Range[Length[data]]}]]

LabeledListPlot[data:{{_?numberQ, _}..}, opts___] :=
        LabeledListPlot[Transpose[Join[Transpose[data], {Range[Length[
data]]}]]]

LabeledListPlot[data:{{_?numberQ, _?numberQ, _}..}, opts___] :=
	Show[Graphics[ {PointSize[0.015], {Point[Take[#, 2]], 
		Text[Last[#], Scaled[{0.015, 0}, Take[#, 2]], {-1, 0}]
			} } & /@ data ,
		opts, Axes->Automatic]]

(* LogPlot *)

SetAttributes[LogPlot, HoldAll]

LogPlot[f_List, {x_, xmin_, xmax_}, opts___] :=
	Module[{r,
               g = Plot[Evaluate[Log[10,f]], {x, xmin, xmax},
			Ticks->{Automatic,LogScale},
			FrameTicks -> {Automatic, LogScale,
				       Automatic, LogScale},
			DisplayFunction -> Identity, opts]},
        r = PlotRange[g];
        Show[g, DisplayFunction -> $DisplayFunction,
        PlotRange ->{Floor[r[[2,1]]],Ceiling[r[[2,2]]]}, 
			AxesOrigin -> {r[[1,1]], Floor[r[[2,1]]]}]]
        		
LogPlot[f_, {x_, xmin_, xmax_}, opts___] :=
	Module[{r,
               g = Plot[Log[10,f], {x, xmin, xmax},
			Ticks->{Automatic,LogScale},
			FrameTicks -> {Automatic, LogScale,
				       Automatic, LogScale},
			DisplayFunction -> Identity, opts]},
        r = PlotRange[g];
        Show[g, DisplayFunction -> $DisplayFunction,
        PlotRange ->{Floor[r[[2,1]]],Ceiling[r[[2,2]]]}, 
			AxesOrigin -> {r[[1,1]], Floor[r[[2,1]]]}]]
        		

(* LogListPlot *)

LogListPlot[data:{_?numberQ ..}, opts___] :=
	Module[{r,
	       g = ListPlot[ N[Log[10, #]]& /@ data,
				Ticks->{Automatic,LogScale},
				FrameTicks -> {Automatic, LogScale,
				       	       Automatic, LogScale},
				DisplayFunction -> Identity, opts ]},
		r = PlotRange[g];
		Show[g, DisplayFunction -> $DisplayFunction,
			PlotRange ->{Floor[r[[2,1]]],Ceiling[r[[2,2]]]}, 
			AxesOrigin -> {r[[1,1]], Floor[r[[2,1]]]}]]

LogListPlot[data:{{_?numberQ, _}..}, opts___] :=
	Module[{r,
	       g = ListPlot[ {First[#], N[Log[10, Last[#]]]}& /@ data,
			Ticks->{Automatic,LogScale}, 
                        FrameTicks -> {Automatic, LogScale,
                                       Automatic, LogScale},
			DisplayFunction -> Identity, opts ]},
		r = PlotRange[g];
		Show[g, DisplayFunction -> $DisplayFunction,
			PlotRange -> r, AxesOrigin -> Map[#[[1]]&,r]]]

(* LogLogPlot *)

SetAttributes[LogLogPlot, HoldAll]

LogLogPlot[f_List, {x_, xmin_, xmax_}, opts___] :=
	Module[{r,
               g = ParametricPlot[Evaluate[Transpose[
			Thread[{Log[10,x], Log[10,f]}] ]],
			{x, xmin, xmax},
                	Ticks->{LogScale, LogScale}, 
                        FrameTicks -> {LogScale, LogScale,
                                       LogScale, LogScale},
                	DisplayFunction -> Identity, opts]},
        r = PlotRange[g];
        Show[g, DisplayFunction -> $DisplayFunction,
        		PlotRange -> r, AxesOrigin -> Map[#[[1]]&,r]]]

LogLogPlot[f_, {x_, xmin_, xmax_}, opts___] :=
	Module[{r,
               g = ParametricPlot[{Log[10,x], Log[10,f]}, {x, xmin, xmax},
                	Ticks->{LogScale, LogScale}, 
                        FrameTicks -> {LogScale, LogScale,
                                       LogScale, LogScale},
                	DisplayFunction -> Identity,
			PlotDivision -> 1000000,
			MaxBend -> 1, opts]},
        r = PlotRange[g];
        Show[g, DisplayFunction -> $DisplayFunction,
        		PlotRange -> r, AxesOrigin -> Map[#[[1]]&,r]]]



BodeMagnitudePlot[f_, {x_, xmin_, xmax_}, opts___] :=
	Module[{r,
               g = ParametricPlot[{Log[10,x], 20*Log[10,Abs[f]]}, 
	       		{x, xmin, xmax},
                	Ticks->{LogScale, Automatic}, 
                        FrameTicks -> {LogScale, Automatic,
                                       LogScale, Automatic},
                	DisplayFunction -> Identity, 
			PlotDivision -> 10000,
			MaxBend -> 0.05,opts]},
			
        r = PlotRange[g];
        Show[g, DisplayFunction -> $DisplayFunction,
        		PlotRange -> r, AxesOrigin -> Map[#[[1]]&,r]]]


BodePhasePlot[f_, {x_, xmin_, xmax_}, opts___] :=
	Module[{r,
               g = ParametricPlot[{Log[10,x], 
	       If[Arg[f]> 0,(Arg[f]-2*Pi)*180/Pi,Arg[f]*180/Pi]}, 
	       		{x, xmin, xmax},
                	Ticks->{LogScale, Automatic}, 
                        FrameTicks -> {LogScale, Automatic,
                                       LogScale, Automatic},
                	DisplayFunction -> Identity, 
			PlotDivision -> 10000,
			MaxBend -> 0.1,opts]},
        r = PlotRange[g];
        Show[g, DisplayFunction -> $DisplayFunction,
        		PlotRange -> r, AxesOrigin -> Map[#[[1]]&,r]]]

BodePhasePlot180[f_, {x_, xmin_, xmax_}, opts___] :=
	Module[{r,
               g = ParametricPlot[{Log[10,x], 
	       If[Arg[f]> 0,(Arg[f]-0*Pi)*180/Pi,Arg[f]*180/Pi]}, 
	       		{x, xmin, xmax},
                	Ticks->{LogScale, Automatic}, 
                        FrameTicks -> {LogScale, Automatic,
                                       LogScale, Automatic},
                	DisplayFunction -> Identity, 
			PlotDivision -> 10000,
			MaxBend -> 0.1,opts]},
        r = PlotRange[g];
        Show[g, DisplayFunction -> $DisplayFunction,
        		PlotRange -> r, AxesOrigin -> Map[#[[1]]&,r]]]


(* LogLogListPlot *)

LogLogListPlot[data:{_?numberQ ..}, opts___] :=
	Module[{r,
     	       g = ListPlot[ 
			Transpose[
			{ N[Log[10, #]]& /@ Range[Length[data]],
			  N[Log[10, #]]& /@ data }
			], Ticks->{LogScale,LogScale}, 
                           FrameTicks -> {LogScale, LogScale,
                                          LogScale, LogScale},
			DisplayFunction -> Identity, opts ]},
		r = PlotRange[g];
		Show[g, DisplayFunction -> $DisplayFunction,
			PlotRange -> r, AxesOrigin -> Map[#[[1]]&,r]]]
 
LogLogListPlot[data:{{_?numberQ, _}..}, opts___] :=
	Module[{r,
     	       g = ListPlot[ N[Log[10, #]]& /@ data, 
                	Ticks->{LogScale,LogScale},
                        FrameTicks -> {LogScale, LogScale,
                                       LogScale, LogScale},
                	DisplayFunction -> Identity, opts ]},
         	r = PlotRange[g];
         	Show[g, DisplayFunction -> $DisplayFunction,
         		PlotRange -> r, AxesOrigin -> Map[#[[1]]&,r]]]

(* PolarPlot  *)

SetAttributes[PolarPlot, HoldAll]

PolarPlot[r_List, {t_, tmin_, tmax_}, opts___] :=
	ParametricPlot[Evaluate[Transpose[{r Cos[t], r Sin[t]}]],
		{t, tmin, tmax}, opts, AspectRatio->Automatic]

PolarPlot[r_, {t_, tmin_, tmax_}, opts___] :=
	ParametricPlot[{r Cos[t], r Sin[t]}, {t, tmin, tmax}, opts,
		AspectRatio->Automatic]

(* PolarListPlot *)

PolarListPlot[rlist_List, opts___] :=
	ListPlot[ rlist * Map[{Cos[#], Sin[#]}&, 
			2Pi/Length[rlist] Range[0, Length[rlist]-1]], 
	opts, AspectRatio->Automatic ]

(* ErrorListPlot *)

ErrorListPlot[l2:{{_, _}..}] :=
        Module[ {i}, 
	ErrorListPlot[ Table[Prepend[l2[[i]], i], {i, Length[l2]}] ] ]

ErrorListPlot[l3:{{_, _, _}..}] :=
        Show[ Graphics[ { PointSize[0.015], Thickness[0.002],
                Module[ {i, x, y, dy} , 
                Table[ 
                        {x, y, dy} = l3[[i]] ;
                        { Line[ {{x, y-dy}, {x, y+dy}} ],
                        Point[ {x, y} ] } ,
                        {i, Length[l3]}
                ] ] } ], Axes -> Automatic ]

(* BarChart *)

Options[BarChart] = 
	{
	BarStyle -> GrayLevel[0],
	BarEdges -> True,
	BarEdgeStyle -> {GrayLevel[0], Thickness[.002]},
	BarSpacing -> 0.9,
	BarOrientation -> Vertical
	};

BarChart[list:{_?numberQ..}, opts___] :=
	BarChart[Transpose[{list, Range[Length[list]]}], opts]

BarChart[list:{{_?numberQ, _}..}, opts___] :=
	Module[{style},
		style = BarStyle /. {opts} /. Options[BarChart];
		BarChart[Map[Append[#, style]&,list], opts]
	]

BarChart[list:{{_?numberQ, _, _}..}, opts___] :=
	Module[{edges, edgestyle, spacing, orient,
		gopts, halfwidth, g1, g2, g, n, clist, ticks},
		{edges, edgestyle, spacing, orient} =
		{BarEdges, BarEdgeStyle, BarSpacing,
			BarOrientation} /. 
			{opts} /. Options[BarChart] ;
		If[!(0 <= spacing <= 1), 
			Message[BarChart::spacing, spacing]; spacing=0] ;
		If[!(edges===True || edges===False), 
			Message[BarChart::edges, edges]; edges=True] ;
		If[(orient!=Horizontal && orient!=Vertical),
			Message[BarChart::orient, orient]; orient=Vertical] ;
		gopts = Select[{opts}, 
			(!MemberQ[{BarStyle, BarEdges, 
				BarEdgeStyle, BarSpacing, 
				BarOrientation}, First[#]])&] ;
		halfwidth = N[(1 - spacing)/2] ;
		clist = Map[First, list] ;
		If[orient === Vertical, 
			g1 = Table[{list[[n,3]],Rectangle[ {n-halfwidth, 0},
			{n+halfwidth, clist[[n]]} ]}, {n, Length[list]} ],
			(* else *)
			g1 = Table[{list[[n,3]],
				Rectangle[ {0, 1+Length[list]-n-halfwidth},
				{clist[[n]], 1+Length[list]-n+halfwidth} ]},
				{n, Length[list]} ]
		] ;
		g = Flatten[g1] ;
		If[edges,
			If[orient===Vertical,
			g2 = Table[ Line[ {
				{n-halfwidth, 0},
				{n-halfwidth, clist[[n]]},
				{n+halfwidth, clist[[n]]},
				{n+halfwidth, 0},
				{n-halfwidth, 0}
				} ], {n, Length[list]} ] ,
			(* else *)
			g2 = Table[ Line[ {
				{0, 1+Length[list]-n-halfwidth},
				{clist[[n]], 1+Length[list]-n-halfwidth},
				{clist[[n]], 1+Length[list]-n+halfwidth},
				{0, 1+Length[list]-n+halfwidth},
				{0, 1+Length[list]-n-halfwidth}
				} ], {n, Length[list]} ]
			] ;
			g2 = Flatten[ Prepend[g2, edgestyle] ] ;
			g = {g, g2} ;
		] ;
		ticks = Table[{n, list[[n,2]]}, {n, Length[list]}];
		g2 = Graphics[g];
		Show[ g2, Flatten[{gopts, 
			Axes -> True,
			If[orient===Vertical,
			AxesOrigin -> {0.5,0},
			AxesOrigin -> {0,0.5}],
			If[orient===Vertical,
			Ticks->{ticks,Automatic}, 
			Ticks->{Automatic,ticks}],
		PlotRange->All}] ]
	]

BarChart::spacing =
"warning: BarSpacing `1` is not between 0 and 1.  Barspacing->0 assumed.";

BarChart::edges =
"warning: BarEdges specification `1` is not True or False.  BarEdges->True
assumed.";

BarChart::orient =
"warning: BarOrientation `1` is not Horizontal or Vertical.  
BarOrientation->Vertical assumed.";

(* PieChart *)

PieChart[list:{_?((numberQ[#] && Positive[N[#]])&) ..}, opts___] :=
	PieChart[ Transpose[ {list, Range[Length[list]]} ], opts ]

PieChart[list:{{_?((numberQ[#] && Positive[N[#]])&), _}..}, opts___] :=
	Module[ {tlist, thalf, text},
		tlist = N[ 2 Pi Drop[FoldList[Plus,0,First /@ list],1] / 
			Apply[Plus, First /@ list] ] ;
		tlist = Prepend[tlist, 0] ;
		thalf = 1/2 Apply[Plus, Partition[tlist, 2, 1], {1} ] ;
		tlist = Map[Line[{{0, 0}, {Cos[#], Sin[#]}}]&, tlist] ;
		text = Table[ Text[ Last[ list[[i]] ], 
			0.7 * {Cos[thalf[[i]]], Sin[thalf[[i]]]} ],
			{i, Length[list]} ] ;
		Show[Graphics[
			{{GrayLevel[0.8], Disk[{0, 0}, 1]}, 
			Thickness[0.002],
			Circle[{0, 0}, 1],
			tlist,
			text},
			AspectRatio->Automatic, opts]]
	]

(* TransformGraphics *)

TransformGraphics[Graphics[list_List, opts___], f_] :=
	Graphics[ TG0[list, f], opts ]

TG0[d_List, f_] := Map[ TG0[#, f]& , d ]

TG0[Point[d_List], f_] := Point[f[d]]

TG0[Line[d_List], f_] := Line[f /@ d]

TG0[Rectangle[{xmin_, ymin_}, {xmax_, ymax_}], f_] :=
	TG0[Polygon[{{xmin,ymin}, {xmin,ymax}, {xmax, ymax}, {xmax, ymin}}], f]

TG0[Polygon[d_List], f_] := Polygon[f /@ d]

TG0[Circle[d_List, r_?numberQ, t___], f_] :=
	Circle[f[d], f[{r,r}], t]

TG0[Circle[d_List, r_List, t___], f_] :=
        Circle[f[d], f[r], t] 

TG0[Disk[d_List, r_?numberQ, t___], f_] :=
        Disk[f[d], f[{r,r}], t] 

TG0[Disk[d_List, r_List, t___], f_] := 
        Disk[f[d], f[r], t]

TG0[Raster[array_, range_List:{{0,0}, {1,1}}, zrange___], f_] := 
	Raster[array, f /@ range, zrange]

TG0[RasterArray[array_, range_List:{{0,0}, {1,1}}, zrange___], f_] := 
	RasterArray[array, f /@ range, zrange]

TG0[Text[expr_, d_List, opts___], f_] := Text[expr, f[d], opts]

TG0[expr_, f_] := expr

(* SkewGraphics *)

SkewGraphics[g_, m_?MatrixQ] :=
	TransformGraphics[g, (m . #)&]

End[ ]   (* Graphics`Graphics`Private` *)
EndPackage[ ]   (* Graphics`Graphics` *)


(*:Limitations: none known. *)

(*:Tests:

*)

(*:Examples:

LinearScale[ 1,2]

LogScale[1,10]

UnitScale[2,10,0.7]

PiScale[ 0,10]

TextListPlot[{{1.5, 2.5}, {1.6, 2.6}, {1.7, 2.7}, {1.8, 2.8}}]

TextListPlot[{ {1.5,2.5,1},{1.6,2.6,2},{1.7,2.7,3},{1.8,2.8,4}}]

LabeledListPlot[{ {1.5,2.5,1},{1.6,2.6,2},{1.7,2.7,3},{1.8,2.8,4}}]

LogPlot[ Sin[x],{x,0.1,3.1}]

LogPlot[ Exp[ 4 x], {x,1,5}, Frame -> True]

LogPlot[ Exp[ 4 x], {x,1,5}, Frame -> True,
	GridLines -> {Automatic, LogGridMajor}]

LogPlot[ Exp[ 4 x], {x,1,3}, Frame -> True,
	GridLines -> {Automatic, LogGridMinor}]

LogListPlot[ Table[i,{i,10}] ]

LogListPlot[ Table[ {i/2,i^2},{i,20}]]

LogLogPlot[ Sin[x],{x,0.1,3.1}]

LogLogListPlot[ Table[ i^2,{i,10}]]

LogLogListPlot[ Table[ {i^2,i^3},{i,10}]]

PolarPlot[ Cos[t], {t,0,2 Pi}]

PolarPlot[ {Cos[t], Sin[2 t]},{t,0,2 Pi}]

PolarListPlot[ Table[ {t/2,Cos[t]},{t,0,2 Pi, .1}]]

ErrorListPlot[Table[ { i,i^2},{i,10}]]

ErrorListPlot[ Table[ { Sin[t],Cos[t], t},{t,10}]]

BarChart[ Table[i,{i,1,10}]]

BarChart[ Table[ {Sin[t], SIN[t]},{t,0.6,3,0.6}]]

PieChart[ Table[ i,{i,5}]]

PieChart[ Table[ {i,A[i]},{i,7}]]

PlotStyle[Plot[Sin[x],{x,0,Pi}]]

PlotStyle[Plot[Sin[x],{x,0,Pi},
	PlotStyle->{{Dashing[{.02,.02}],Thickness[.007]}}]]

g1 = Plot[t,{t,0,Pi}]; Show[ TransformGraphics[ g1, Sin[#]& ] ]

g1 = Plot[ Sin[t],{t,0,Pi}]; Show[ SkewGraphics[g1, {{1,2},{0,1}}]]

*)