21

Short version: Is there a value for the FrameTicks option that retains the default tick marks on all sides, and puts tick labels only on the right and top sides?


I can imagine all manner of cleverness with FontOpacity, FontSize, ImagePadding, etc. (for example) to achieve the desired appearance in the example use case below, but, for a number of reasons, in this post I would like to focus on the question as it is worded (under Question heading).


The example below shows what frameticks look like by default.

Graphics[{}, ImageSize -> Small, Frame -> True]

Mathematica graphics

In other words, the default specification for frame ticks can be described in English as:

(default spec)

  1. Tick marks are to be placed on all sides;
  2. Tick labels are to be placed on the left and bottom sides only.

Now, suppose one wants the ticks done according to a small variation of this default spec, one that retains part 1 of the default spec, but changes part 2. For example:

(custom spec)

  1. Tick marks are to be placed on all sides;
  2. Tick labels are to be placed on the right and top sides only.

One approach to achieve this result, of course, is to provide full-blown, explicit tick specifications of the form

{{x1, label1, len1, style1}, …}

...as the values of left, right, bottom, top in

FrameTicks -> {{left, right}, {bottom, top}}

This approach is a pain in the butt, of course, but worse still, it does not come close to matching the generality and maintainability of the default1.


The only other documented possibility is to use some combination of the symbolic settings None, Automatic, True, and/or All.

In search for the "magic combination", I tried the expression

Graphics[{}, ImageSize -> Small, Frame -> True, FrameTicks -> {{a, b}, {a, b}}]

for all possible combinations of values for a and b. (I made a chart of the results for future reference; I've appended it at the end of this post.) The only one that came close to implementing the desired spec was a = None, b = All:

Graphics[{}, ImageSize -> Small, Frame -> True,
         FrameTicks -> {{None, All}, {None, All}}]

Mathematica graphics

This result comes up short because it does not satisfy part 1 of the desired specification.

Bottom line, I have not managed to find a documented setting for FrameTicks that implements the desired spec.


Question

My main question is:

In addition to the one consisting of explicit tick specifications, is there some other (most likely undocumented) value for the FrameTicks option that implements the custom spec above?


Secondarily, I'm also curious to know if there is some documentation that explains why the custom spec above needs to be made so difficult to implement robustly.


P.S. For future reference, in the chart below, the label next to each side gives its FrameTick.

Mathematica graphics

Notes

  1. In all cases, left and bottom have the same setting, and likewise for the settings for right and top.

  2. Along each row, the settings for left and bottom are constant. Along each column, the settings for right and top are constant.

  3. The effect of the True setting (ironically enough) is not universally consistent; it depends on which side it is applied to. On the left and bottom, the effect is "ticks and labels"; on the right and top, it is "ticks only; no labels". (The same could be said of the Automatic setting, but this is reasonable under the interpretation of Automatic as "default".)


1For example, I don't know how I could use this approach in a function that takes some data as input and produces a framed plot that meets the custom tick specification.

kjo
  • 11,717
  • 1
  • 30
  • 89
  • 1
    I moved your distinguishing statement to the top of the is question as to one degree or another the first three answers posted, mine being one of them, all seem to have ignored it. I deleted my answer which was just an example of ImagePadding. – Mr.Wizard Mar 25 '17 at 14:47
  • 3
    @corey979: Mathematica is huge, and its documentation is often incomplete. Knowing that something is not implemented is, in itself, useful information. It saves people a futile search. – kjo Mar 25 '17 at 16:01

3 Answers3

12

Following the strict requirements of your question the nearest solution I can offer is this.

I use the internal tick generating function to behave as All does, but remove the labels.

Edit: I found that what I wrote is already implemented in Charting`ScaledFrameTicks.

magic = Charting`ScaledFrameTicks[{# &, # &}];

Graphics[{}
 , Frame -> True
 , FrameTicks -> {{magic, All}, {magic, All}}
]

enter image description here

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
  • One weird thing with Charting\ScaledFrameTicks` is that many of the ticks disappear, as you can see on the bottom edge of your example. Can this be fixed? – Alex Bogatskiy Jul 10 '23 at 16:53
8

FrameTicks together with FrameTicksStyle do it (as far as I know it's not possible with FrameTicks only:

Graphics[{}, ImageSize -> Small, Frame -> True, FrameTicks -> All, 
 FrameTicksStyle -> {{Directive[FontOpacity -> 0, FontSize -> 0], Automatic},
                     {Directive[FontOpacity -> 0, FontSize -> 0], Automatic}}]

enter image description here

(obtained with $Version: "10.4.1 for Linux x86 (64-bit) (April 11, 2016)").


As pointed out by Szabolcs, in v10.0 (and later) on OSX this does not crop the image, but leaves large borders on the bottom and left. The solution is to change FontSize -> 0 to FontSize -> 0.1.

corey979
  • 23,947
  • 7
  • 58
  • 101
  • 1
    Thanks. I tried to rule out this solution in my PS, but I guess I was not explicit enough. – kjo Mar 25 '17 at 13:44
  • FrameTicks are ticks + labels; ruling out one rules out the other. I very recently was searching for a solution to a similar issue and came up with altering the font options of FrameTicks via FrameTicksStyle. I highly doubt there's a simpler method to achieve this goal (although I would like to find out I'm mistaken). – corey979 Mar 25 '17 at 13:49
  • 1
    This will not remove the labels: it will leave enough padding for them. But it's good as a quick and dirty solution. – Szabolcs Mar 25 '17 at 13:50
  • @Szabolcs Technically it does not remove the labels, but makes them infinitesimally small, cropping the image as much as (by default) possible: https://imgur.com/a/IB4eE – corey979 Mar 25 '17 at 13:57
  • @Szabolcs Why the edit? – corey979 Mar 25 '17 at 13:58
  • @corey979 For some reason it doesn't work on my machine, M11.1 on OS X. Before I saw your comment, I tried it. I copied your code, evaluated it, exported the result, and inserted it into your post (with a yellow background to make the size of the white image clear). Despite the FontSize -> 0, I still see large borders. Do you not get these on your machine? – Szabolcs Mar 25 '17 at 13:59
  • @corey979 The edit was to make the size of the borders clear. I did not see your comment when I made the edit. I thought that you uploaded a screenshot instead of an actual exported figure, and that you unknowingly cropped the borders. Now I realize that that is not the case. But let's figure out why we get different things. What's your version and OS? – Szabolcs Mar 25 '17 at 14:00
  • @Szabolcs No, see my original image and https://imgur.com/a/IB4eE. But I'm on v10.4.1 and that's the output I get. – corey979 Mar 25 '17 at 14:01
  • What OS are you using? This is what I get in 10.4.1: http://i.stack.imgur.com/EAwQY.png Can you spot the problem? – Szabolcs Mar 25 '17 at 14:02
  • Maybe it's OS dependent; see edit. – corey979 Mar 25 '17 at 14:04
  • It seems that on my computer, FontSize -> 0 does not work in any version. However, FontSize -> 0.1 does work, and produces the result you showed. Maybe mention this in your post. I'm on OS X. – Szabolcs Mar 25 '17 at 14:04
  • @cory979 "FrameTicks are ticks + labels": that depends on which side one refers to. – kjo Mar 25 '17 at 14:12
  • Sorry, and thanks for the edit! +1, this weirdness with a zero font size can be very confusing and is good to point out. – Szabolcs Mar 25 '17 at 14:14
  • corey979, I just got to the part of the question I can imagine all manner of cleverness with FontOpacity, FontSize, ImagePadding which disqualified my hack and well as your answer, so I deleted mine and put a -1 on yours. Sorry. By the way you were entirely right about my hack not working so well. – Mr.Wizard Mar 25 '17 at 14:43
  • @Mr.Wizard I don't agree with the downvote. If anyone shows how to do it with FrameTicks only, I will also remove my answer. As far as I understand, it's not possible to achieve the result without additional options (SciDraw is not only an options, but whole package, so it also does not fit in the requirements). So maybe this question should be closed as one that asks for a feature that is not possible? – corey979 Mar 25 '17 at 14:47
  • @corey979 I also think it is not possible as written. However that doesn't make your post an answer to the question. kjo was already aware of this method even though he didn't make that prominently clear in his original Question. – Mr.Wizard Mar 25 '17 at 14:53
  • @corey979 Whether or not this should be closed is a separate issue. I don't know if there exist clear guidelines for that. I have also asked for features that do not exist (346), and one of the more popular questions on this site was mostly of that type (1953). However in other cases we have closed questions where the OP seems to simply want Mathematica to work like another product and isn't open to alternatives, etc. – Mr.Wizard Mar 25 '17 at 15:00
  • I appreciate this discussion, but isn't the need for it kind of ridiculous in the first place? This isn't a particularly odd or unique thing to ask for... – Ben Kalziqi Aug 08 '18 at 20:41
6

With CustomTicks (part of SciDraw, but also usable independently) it's easy to truly remove the tick labels:

Needs["CustomTicks`"]
(* Optional: adjust tick style. Done here so one can better see the ticks *)

linestyle = {AbsoluteThickness[1], Black};

SetOptions[LinTicks, MajorTickLength -> {0.04, 0}, 
  MinorTickLength -> {0.015, 0}, MajorTickStyle -> linestyle, 
  MinorTickStyle -> linestyle];
(* actual plot *)
Graphics[{}, ImageSize -> Small, Frame -> True, 
 FrameTicks -> {StripTickLabels[LinTicks], StripTickLabels[LinTicks], 
   LinTicks, LinTicks}]

enter image description here

Szabolcs
  • 234,956
  • 30
  • 623
  • 1,263
Felix
  • 3,871
  • 13
  • 33