Group Abstract Group Abstract

Message Boards Message Boards

1
|
7.5K Views
|
11 Replies
|
5 Total Likes
View groups...
Share
Share this post:

Set custom Graphics axes directions?

Posted 5 years ago

By default in Graphics, the axes run from left to right (x) and bottom to top (y). Often one needs different directions, in particular, the y-axes running from top to bottom.

I cannot find an option with determines axes directions. Any help?

POSTED BY: Werner Geiger
11 Replies

Hi Neil,

Could you please point me to where you've seen the comment that ScalingFunction does not apply to any options? The only relevant comment that I've found in the documentation is one stating "Options are specified in the original coordinates". Which I've read as meaning that graphics coordinates specified in Prolog/Epilog and other option expressions should not need to be individually scaled. But, for the Epilog and Prolog options at least, the coordinates of graphics expressions do need to be scaled. From what you say, I may be missing something in the documentation. Or I could be completely misunderstanding it. Which is perfectly possible ;-)

Irrespective of what the documentation says, I think that when ScalingFunctions are specified they should be applied to the data and all options. I can't think of a case where this wouldn't be the intention and not doing so just presents us with a headache and unnecessary extra work.

For me, there seems to be some inconsistency in how ScalingFunctions are applied to options. This is illustrated in the attached notebook, which gives examples that show ScalingFunctions are not applied to the Prolog and Epilog options but are applied to the PlotRange option.

So, if this behaviour is not a bug and is intentional, as you suggest, my view is that it should be changed.

All the best,

Ian

Attachments:
POSTED BY: Ian Williams

I would not wait for a “fix” — It’s not considered a bug because it is documented that way. If you look up ScalingFunction it says that it does not apply to any options (which includes prolog, etc). If you want a change of behavior, I think you should contact @Arnoud Buzing by email and make your arguments. There may be good reason for this (I have no idea and have not thought it through)

Regards

Neil

POSTED BY: Neil Singer
Posted 5 years ago

Bug or not, who knows. For my point of view, it's not logical and pretty useless how it works now:

  • Applied to Plot, but not Graphics.
  • Not applied to Pro/Epilog, see Ian.

I don't know, how to reach Arnoud Buzing. I tried to place the issue at enter link description here

POSTED BY: Werner Geiger

One thing to be aware of if you set ScalingFunctions->"Reverse" is that the corresponding coordinate values of any graphics expressions given in Prolog or Epilog will not be reversed. This caught me out when I first started using ScalingFunctions->"Reverse" - it took me a wile to figure out why the graphics object specified in Epilog wasn't being plotted. Once you know what's going on, this fix is simple - you just need to negate the relevant coordinate values used in Prolog/Epilog. But it's a bit of a pain. The issue has been there for as long as I've been using Mathematica and feels like a bug to me. I certainly haven't found any mention of the behaviour in the documentation. Maybe it'll be fixed in 12.1 - fingers crossed, but I'm not holding my breath ;-)

POSTED BY: Ian Williams
Posted 5 years ago

I think as well, that's a bug. I can't imagine any reason why not all coordinates could be transformed automatically by the ScalingFunctions-option. Nor that it is not supported in Graphics (but - surprise! - accepted). The underlying transformations are trivial.

Do you know, when 12.1 will arrive?

POSTED BY: Werner Geiger

Maybe you can mimic your graphic using ListPlot and friends. Then there is the option ScalingFunctions -> "Reverse", e.g.:

pts = RandomReal[{-1, 1}, {10, 2}];
gr = Graphics[{EdgeForm[Thick], White, Polygon[pts]}, Frame -> True, PlotLabel -> "Graphics"];
llp = ListLinePlot[Append[pts, First[pts]], Joined -> True, ScalingFunctions -> "Reverse", Frame -> True, AspectRatio -> Automatic, PlotLabel -> "ListLinePlot (Reverse)"];
GraphicsRow[{gr, llp}]

enter image description here

Does that help?

POSTED BY: Henrik Schachner
Posted 5 years ago

Thanks a lot, Henrik. This does what I want to do. I've stupidly overlooked the option ScalingFunctions so far.

Unfortunately, it works for the Plot-functions only, but not for Graphics. Strange enough, for Graphics it is accepted, marked red but ignored.

The following code draws a broken line with all four axis orientations. Once with Graphics as an Arrow and once with ListLinePlot as a Line. Everything else is identical.

You can see that ListLinePlot does everything right. (Maybe except for the AxesLabel, which are not placed at the correct position at the end of the axis).

Block[{graphs, i, pts, xticks, yticks},
 pts = {{0, 0}, {1.5, 0.25}, {2, 1}};
 xticks = 0.5*Range[4]; yticks = 0.25*Range[4];
 graphs = Table[{Null, Null}, 4]; i = 0;
 Do[i++;
  graphs[[i, 1]] = Graphics[Arrow[pts]
    , Axes -> True, AxesStyle -> Directive[Red, 12], 
    ScalingFunctions -> sfs
    , AxesLabel -> (Style[#, Red, Bold, 16] & /@ {"x", "y"})
    , Ticks -> {xticks, yticks}, GridLines -> {xticks, yticks}
    , PlotLabel -> 
     Style[Column[{"Graphics", 
        Row[{"ScalingFunctions\[Rule]", sfs // InputForm}]}, Center], 
      Blue]
    , ImageSize -> Medium];
  graphs[[i, 2]] = ListLinePlot[pts
    , Axes -> True, AxesStyle -> Directive[Red, 12], 
    ScalingFunctions -> sfs
    , AxesLabel -> (Style[#, Red, Bold, 16] & /@ {"x", "y"})
    , Ticks -> {xticks, yticks}, GridLines -> {xticks, yticks}
    , PlotLabel -> 
     Style[Column[{"ListLinePlot", 
        Row[{"ScalingFunctions\[Rule]", sfs // InputForm}]}, Center], 
      Blue]
    , ImageSize -> Medium]
  , {sfs, {{None, None}, {None, "Reverse"}, {"Reverse", 
     None}, {"Reverse", "Reverse"}}}
  ];
 Print[graphs]
 ]

enter image description here

enter image description here

POSTED BY: Werner Geiger
Posted 5 years ago

@Rohit: Well, this are still standard axes. y is running from the bottom (-3) to top (0). You just changed the labeling of ticks, not the coordinate system.

You can achieve the same with the standard Ticks option.

Block[{pt, yTicks},
 pt = {2, -2}; yTicks = {#, -#} & /@ Range[-3, 0, 0.5];
 Graphics[{Circle[pt, 1],
   Arrow[{{0, 0}, pt}], Red, PointSize -> Large, Point[pt], 
   Inset[Style[pt, 12], pt, {0, 2.0}]}
  , Axes -> True, AxesOrigin -> {0, 0}, Ticks -> {Automatic, yTicks}]
 ]

enter image description here

POSTED BY: Werner Geiger
Posted 5 years ago

Hi Werner,

You could try the undocumented Charting`ScaledTicks function.

Graphics[Circle[{2, -2}, 1], Axes -> True, AxesOrigin -> {0, 0}, 
 Ticks -> {Automatic, Charting`ScaledTicks["Reverse"][##, {12, 6}] &}]

enter image description here

But note that you will have to flip the sign of all y coordinates {2, -2} above.

POSTED BY: Rohit Namjoshi
Posted 5 years ago

Like this, maybe?

Graphics[Circle[{2,-2},1],Axes->True,AxesOrigin->{0,0}]
POSTED BY: Hans Milton
Posted 5 years ago

No. This are standard axes. y is running from the bottom (-3) to top (0).

What I want is y=0 on top and y=3 on the bottom. I.e. the standard way how by example screen display points are addressed (origin at top left).

POSTED BY: Werner Geiger
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard