When displaying a scatterplot using Graphics, is there a way to use the automatic range for the x and y axes, but force the origin to be centered in the image?

Clarification: I'm trying to force the point (0,0) to be in the center of the graphic, and the axes ranges determined appropriately. i.e. x and y:

PlotRange -> ({-Max[Abs[Data]]), (Max[Abs[Data]])}, {-Max[Abs[Data]]), (Max[Abs[Data]])})

I'm computing a few thousand graphs this way, and computing these ranges literally as above takes a while. I was hoping there were a simple Graphics option. Thanks!

  • 1
    $\begingroup$ Please post code. $\endgroup$ – David G. Stork Feb 8 '19 at 1:23

Alan has the right idea, but if you are using Graphics rather than ListPlot, then it would go like this:

SeedRandom[1]; pts = RandomInteger[100, {50, 2}];
With[{center = Mean /@ Transpose[pts]},
  Graphics[Point[pts], Axes -> True, AxesOrigin -> center]]


| improve this answer | |
pts = RandomReal[{0, 1}, {50, 2}]
ListPlot[pts, AxesOrigin -> (Mean /@ Transpose@pts)]
| improve this answer | |
  • $\begingroup$ (+1) you can use Mean@pts instead of Mean /@ Transpose@pts (Mean is Listable). $\endgroup$ – kglr Feb 8 '19 at 7:30
  • $\begingroup$ Thanks! I clarified my question a bit, however, as this was not quite what I meant. $\endgroup$ – user413587 Feb 8 '19 at 15:29

It seems difficult to use PlotRange->Automatic for this because we don't know the algorithm it uses. The function below accepts a list of points and a number sdevs which gives the number of standard deviations to include each side of the center. The example uses 3. Optional options are passed to ListPlot. Like for PlotRange->Automatic, some points may be outside the range of the plot and not shown.

pts = RandomReal[{0, 1}, {50, 2}];

centeredListPlot[points_, sdevs_, opts___] := 
 Module[{xvals, yvals, cx, cy, center, sx, sy, xRange, yRange},
  xyValues = Transpose@points;
  (* the center *)
  {cx, cy} = Mean /@ xyValues;
  (* sdevs standar deviations from center *)
  {sx, sy} = StandardDeviation /@ xyValues;
  xRange = cx - sdevs {-sx, sx};
  yRange = cy - sdevs {-sy, sy};
  ListPlot[points, PlotRange -> {xRange, yRange} // Evaluate, 
   AxesOrigin -> {cx, cy}, opts]

centeredListPlot[pts, 2, PlotLabel -> "Centered Plot"]

enter image description here

| improve this answer | |

I am not sure this is what you want.

data1 = RandomInteger[{-40, 40}, {50, 2}];
data2 = RandomInteger[{0, 100}, {50, 2}];
data3 = RandomInteger[{-100, 100}, {50, 2}];

data = Join @@ {data1, data2, data3};

max = Max@data;

range = {{-max, max}, {-max, max}};

ListPlot[{data1, data2, data3}, PlotRange -> range, AspectRatio -> 1, 
 PlotLegends -> Automatic]

enter image description here

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.