Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I would like to draw diagonal tick marks around a plot, and simultaneously rotate the tick labels as well. I've mocked up what this would look like:

enter image description here

Is there an easy way to do this in Mathematica? I believe this is beyond the capabilities of the CustomTicks package.

Edit: I would like this to be general enough to work for arbitrary plot ranges, and perhaps it would be easiest to generate the plot first with the normal tick marks, and then apply a replacement to the final graphics object?

share|improve this question
    
Can you just define a graphics object, something like: tick[startx_,starty_,n_] :=Graphics[Text[Style[ToString[n] <> ".0", 30], {startx - 0.8, starty - 0.8}, Automatic, {1, 1}]],Graphics[Line[{{startx,starty}, {startx - 0.5, starty - 0.5}}]] and add it onto a plot with all Ticks removed? –  Jonathan Shock Apr 24 '13 at 3:05
    
Related / a possible starting point: How to align rotated tick labels? –  Yves Klett Apr 24 '13 at 7:09
    
I believe it's possible to use fixed FullGraphics function from here, and rotate the ticks. –  swish May 4 '13 at 2:03

2 Answers 2

up vote 10 down vote accepted

This was a bit harder -- and turned out more complicated -- than I thought it would be at first, mainly because at first I didn't think ahead to what would be required: To do the ticks and rotate them, you need to know the full plot range, including the padding, and the aspect ratio. Moreover, AbsoluteOptions does not work the way that would make it easy to figure these things out (unless I'm missing something).

In any case, this seems to work. The shared variables are localized in a Module containing the definitions.

Module[{
   plotrange0,          (* PlotRange *)
   plotrangepadding0,   (* PlotRangePadding *)
   aspectratio,         (* aspect ratio as a pair {x, y} *)
   xticks, yticks,      (* ranges for ticks (full plotrange) *)
   dplotrange,          (* width, height of full plotrange *)
   ticks,
   ticklen = 0.025,     (* length of ticks (const parameter) *)
   textoffset = 0.005}, (* how far from ticks to end of label (const parameter) *)

   (* convert PlotRangePadding setting to coordinate offsets *)
 paddingcvt[range_, {padX_, padY_}] := {{-1, 1} padX /. 
    Scaled[s_] :> s (range[[1, 2]] - range[[1, 1]]), {-1, 1} padY /. 
    Scaled[s_] :> s (range[[2, 2]] - range[[2, 1]])};
 paddingcvt[range_, padding_] := {{-1, 1} padding /. 
    Scaled[s_] :> s (range[[1, 2]] - range[[1, 1]]), {-1, 1} padding /. 
    Scaled[s_] :> s (range[[2, 2]] - range[[2, 1]])};
   (* calculate the plot range plus padding *)
 fullplotrange[] := plotrange0 + paddingcvt[plotrange0, plotrangepadding0];
   (* returns rotated ticks along side : tickposfn = {#, y0} or {x0, #} *)
 tickGraphics[tickrange_, Function[tickposfn_]] := GeometricTransformation[
     {Text[N@#, Scaled[{-ticklen - textoffset, 0}, tickposfn], {1, 0}], 
      Line[{Scaled[{-ticklen, 0}, tickposfn], tickposfn}]},
     rotate[\[Pi]/4, tickposfn]] & /@ 
   Select[FindDivisions[tickrange, 5], tickrange[[1]] < # < tickrange[[2]] &];
   (* returns transformation to rotate graphics, adjusting for aspect ratio distortion *)
 rotate[\[Theta]_, {a_, b_}] := Composition[
     ScalingTransform[dplotrange/aspectratio, #],
     RotationTransform[\[Theta], #],
     ScalingTransform[aspectratio/dplotrange, #]] &[{a, b}];

 slantTicks[g_] := ( (* calculate parameters *)
   plotrange0 = PlotRange /. AbsoluteOptions[g, PlotRange];
   plotrangepadding0 = If[# === Automatic, 
       AspectRatio /. AbsoluteOptions[g, PlotRangePadding], #] &[
     PlotRangePadding /. Options[g, PlotRangePadding]];
   {xticks, yticks} = fullplotrange[];
   dplotrange = -Subtract @@@ {xticks, yticks};
   aspectratio = If[# === Automatic, dplotrange, {1, #}] &[
     AspectRatio /. Options[g, AspectRatio]];
     (* the graphics *)
   ticks = Graphics[{AbsoluteThickness[0.5], 
      Line@Tuples[{xticks, yticks}][[{1, 3, 4, 2, 1}]], 
      tickGraphics[xticks, {#, yticks[[1]]} &],
      tickGraphics[yticks, {xticks[[1]], #} &]}, PlotRange -> All];
   Show[g, ticks, Axes -> False, Frame -> None, PlotRangeClipping -> False, 
    ImagePadding -> {{20, 5}, {20, 5}}])
 ]

It works with Plot:

slantTicks[Plot[Sin[Pi x] + Cos[Pi x]^2, {x, 0, 10}]]

Plot output

It works with Graphics:

slantTicks[Graphics[{Red, Thick, Line[{{-0.5, 1.5}, {2.5, 0.55}}]}, 
  PlotRange -> {{-1, 3}, {0, 2}}, PlotRangePadding -> Scaled[0.05]]]

Graphics output

It's not perfect. Note PlotRangeClipping is set to False since ticks are plotted outside the PlotRange of g. There seem to be issues whatever order of ticks and g is used in Show, since the options of the first override the second.

I did try to use Ticks, with which one can rotate the labels with dealing with the aspect ratio. I failed, however, to figure out how to get rotated tick marks in the right places.

share|improve this answer
    
This is great, and exactly what I was looking for! –  Guillochon May 6 '13 at 1:23

It's easy enough, if you like fiddling with values:

p = Plot[Sin[x], {x, 0, 10}];
r = Graphics[{
     FaceForm[None],
     EdgeForm[{Black}],
     Rectangle[{0, -1}, {10, 1}],
     Table[
      {
       Line[{{x - .2, -1.1}, {x, -1}}],
       Text[Style[x, 12], {x - .2, -1.2}, {0, 0}, {1, 1}]
      }, {x, 0, 10}],
     Table[
      {
       Line[{{-.25, y - .1}, {0, y}}],
       Text[Style[y, 12], {-0.5, y - .2}, {0, 0}, {1, 1}]
      }, {y, -1, 1, .5}] 
     }, AspectRatio -> 1/GoldenRatio];
Show[r, p]

plot

If you were going to do a lot of these, it would be worth 'parameterizing' it, to save you fiddling with offsets and values. The problem of the two ticks at {0,0} is interesting, too.

share|improve this answer
1  
That's a twisted use for the word "interesting" –  belisarius Apr 24 '13 at 18:52
    
@belisarius I'm hiding behind its ambiguities... :) –  cormullion Apr 24 '13 at 19:20
    
Just to add here, I am interested in "parameterizing" it. I will be generating hundreds of plots in this style. –  Guillochon May 3 '13 at 23:43

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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