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.

By default, FrameTicks stick into the data area in a way that is sometimes uncomfortable.

Plot[Cos[x], {x, 0, 10}, Frame -> True]

enter image description here

I see that I can create "outie" ticks manually using

Plot[
 Cos[x], {x, 0, 10}, Frame -> True,
  FrameTicks -> {{{0, 0, {0, 0.01}}, {Pi, Pi, {0, .01}}, {2 Pi, 2 Pi, {0, 0.01}}, {3 Pi, 3 Pi, {0, 0.01}}}, {{-1/2, -1/2, {0, 0.01}}, {1/2, 1/2, {0, 0.01}}}, None, None}
]

enter image description here

But I want to use the automatic tick positions, sizes and labels. I can (kind of) achieve this so:

With[
 {originalPlot = Plot[Cos[x], {x, 0, 10}, Frame -> True]},
 Show[originalPlot, 
  FrameTicks -> AbsoluteOptions[originalPlot, FrameTicks][[1, 2]] /. {a_, b_, {c_, d_}, e___} :> {a, b, {d, c}, e}]
 ]

enter image description here

There are (at least) three problems with this approach:

  1. Extra vertical-axis tick labels have been inserted; all vertical-axis ticks appear to have been converted to minor ticks.

  2. Trailing decimal points have been added to the integer tick labels.

  3. FrameStyle no longer affects the ticks, apparently because the ReplaceAll solution hardcodes the FrameTicks style before FrameStyle is applied:

An example of correct application of FrameStyle (with default, "innie" ticks):

Plot[Cos[x], {x, 0, 10}, Frame -> True, FrameStyle -> Gray]

enter image description here

An example of broken application of FrameStyle:

With[
 {originalPlot = Plot[Cos[x], {x, 0, 10}, Frame -> True, FrameStyle -> Gray]},
 Show[originalPlot, 
  FrameTicks -> AbsoluteOptions[originalPlot, FrameTicks][[1, 2]] /. {a_, b_, {c_, d_}, e___} :> {a, b, {d, c}, e}]
]

enter image description here

How can this approach be improved to address these problems?

share|improve this question
    
Unfortunately once you start customizing ticks, you lose most things that automatic ticks provide. What I usually do is use the CustomTicks package (part of LevelScheme) which is very customizable and closely mimics the automatic tick generation. –  Szabolcs Feb 5 '13 at 22:31
    
@Szabolcs I too use LevelScheme sometimes, but it'd be nice to have a native way of doing this. Thanks for the suggestion. –  ArgentoSapiens Feb 5 '13 at 22:33
1  
As I already experienced in this question and @halirutan pointed out to me in chat, there seems to be a bug in AbsoluteOptions that causes the additional ticks. I doubt that there is an easy way to fix this issue. –  einbandi Feb 5 '13 at 22:35
    
Why don't you just use PlotRangePadding? E.g. Plot[Cos[x], {x, 0, 10}, Frame -> True, PlotRangePadding -> {.3, .1}] –  Rolf Mertig Feb 6 '13 at 1:08
    
Closely related: mathematica.stackexchange.com/q/2969/121 –  Mr.Wizard Feb 8 '13 at 5:57
add comment

2 Answers 2

up vote 4 down vote accepted

I wrote a (somewhat buggy) function to do exactly this a while back. It basically takes a plot, finds the ticks, makes them negative length and replots the plot.

outsideTickPlot[plot_] := Module[{ticks, function, newticks},
  ticks = Ticks /. AbsoluteOptions@plot;
  function = {#1, SetPrecision[#2, Infinity], {-1, 1}*#3, #4} &;
  newticks = Apply[function, ticks, {2}];
  Show[plot, Ticks -> newticks]
  ]

and here is an example:

outsideTickPlot[Plot[x^2, {x, 0, 5}]]

Mathematica graphics

share|improve this answer
add comment

The documentation for FrameTicks shows ways to define functions that get passed the minimum and maximum of your data, and then produce the kinds of ticks you require. To get "nice" divisions, use the FindDivisions function. To get "outie" ticks, you need a (small) positive argument in the second element of the pair-list at the end of the list specifying the tick - the 0.005 here.

myticks[min_, max_] := 
 Table[{i, i, {0, 0.005}}, {i, FindDivisions[{min, max}, 10]}]

You can then specify:

Plot[Sin[x], {x , 0 , 4 Pi}, Frame -> True, 
 FrameTicks -> {{Automatic, Automatic}, {myticks[##] &, None}}]

enter image description here

You can be even fancier with a tick function definition like this:

myticks[min_, max_, n_] := 
 Table[{i, 
   Switch[Head[i], Integer, i, Rational, N@i, True, i], {0, 
    0.005}}, {i, FindDivisions[{min, max}, n]}]

This makes sure you don't get fractions as your tick label, while leaving integers alone.

Plot[Sin[x], {x , 0 , 4 Pi}, Frame -> True, 
 FrameTicks -> {{myticks[##, 5] &, myticks[##, 5] &}, {myticks[##] &, None}}]

enter image description here

One thing to watch out for is that "outie" ticks shrink the framed area, the larger you make them, for a given ImageSize. This might matter to you if you are composing your plots in a Grid or something.

share|improve this answer
add comment

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.