5
$\begingroup$

This question already has an answer here:

I'm looking to make a graph with the x-axis reversed and a frame and tick marks that are thicker than default. However, the x-axis tick marks do not maintain the specified thickness once I reverse the x-axis. I can't restore the thickness of the tick marks using TicksStyle or FrameTicksStyle. How can I get around this?

ListLinePlot[{},
 Frame -> True,
 FrameStyle ->
  {{Black, Thickness[0.005]},
   {Black, Thickness[0.005]},
   {Black, Thickness[0.005]},
   {Black, Thickness[0.005]}},
 ScalingFunctions -> {"Reverse", Identity}
 ]

Notice how the tick marks on the y-axis are made thick (as desired), but not along the x-axis:

enter image description here

$\endgroup$

marked as duplicate by Carl Woll, Carl Lange, MarcoB, Alex Trounev, Henrik Schumacher May 12 at 6:45

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

3
$\begingroup$

I think you have found a bug. As far as I can tell, using any scaling option (other than Automatic or None, doesn't annihilate all tick styling, but it does annihilate any attempt to change tick thickness.

Here is supporting evidence.

We start with a ListLinePlot in which we override the frame styling in the top and bottom ticks and their labels.

tickStyle = Directive[Red, AbsoluteThickness[5], FontSize -> 14];

ListLinePlot[Table[{x, Sin[x]}, {x, Subdivide[0, 2 Pi, 100]}],
  Frame -> True,
  FrameStyle -> Thick,
  FrameTicks -> All,
  FrameTicksStyle -> {{None, None}, {tickStyle, tickStyle}}]

plot1

Now let's add scaling.

ListLinePlot[
  Table[{x, Sin[x]}, {x, Subdivide[0, 2 Pi, 100]}],
  Frame -> True,
  FrameStyle -> Thick,
  FrameTicks -> All,
  FrameTicksStyle -> {{None, None}, {tickStyle, tickStyle}},
  ScalingFunctions -> {"Reverse", None}]\

plot2

Note that, while the AbsoluteThickness setting has been ignored, the other style setting are respected. The ticks are still red and the tick labels are still 14 points.

$\endgroup$
  • $\begingroup$ I did find that manually adding in the ticks caused MMA to use the correct styling. It's a painful workaround. I was hoping that tick marks might get some love in 12.0, but aside from one bug fix, I haven't seen that to be the case. $\endgroup$ – MassDefect Apr 16 at 23:25
  • $\begingroup$ @MassDefect Could you explain how you did this (and ideally provide some code?). When I try adding in tick marks manually, the ticks get overridden by Frame->True. $\endgroup$ – Stephen Ting May 6 at 2:25
2
$\begingroup$

If your tick marks are being overridden, it might be that you're using Ticks rather than FrameTicks.

This is how I usually go about making my own tick marks. Unfortunately, that seems to happen a lot more often than I would like.

ticks[min_, max_, stepsz_, majorstep_, minorlength_, majorlength_, 
  labels_] :=
 Table[{
   i,
   If[
    labels \[And] Mod[Rationalize[i], Rationalize[majorstep]] == 0,
    ToString[NumberForm[i, {Infinity, 1}]],
    ""
   ],
   If[
    Mod[Rationalize[i], Rationalize[majorstep]] == 0,
    {majorlength, 0},
    {minorlength, 0}
   ]
  },
  {i, min, max, stepsz}
]

Both Ticks and FrameTicks expect a list in the form { {x1, "x1", {innerlength, outerlength}}, {x2, "x2", {innerlength, outerlength}}, ...}, so my Table constructs a list with that format.

All of the arguments to the function should be numbers, except for labels which should be a boolean (True if you want tick labels on that axis, False otherwise).

One thing to watch out for is the NumberForm inside of ToString. I do that because otherwise MMA likes to output 1. instead of 1.0. So I'm currently forcing it to use 1 decimal place. The number of decimal places you want will probably vary from plot to plot. You could add it in as another argument to the function if you want.

Another tip that might be useful, is I have coded the outside tick length as zero, and my function only allows you to specify the inside length. If you want your ticks on the outside for some graph, you can change that.

This is how you would use the function:

ListLinePlot[
 {},
 Frame -> True,
 FrameTicks -> {{
    ticks[-1, 1, 0.1, 0.5, 0.01, 0.02, True], 
    ticks[-1, 1, 0.1, 0.5, 0.01, 0.02, False]}, 
   {ticks[-1, 1, 0.1, 0.5, 0.01, 0.02, True], 
    ticks[-1, 1, 0.1, 0.5, 0.01, 0.02, False]}},
 FrameStyle -> {{Black, Thickness[0.005]}, {Black, 
    Thickness[0.005]}, {Black, Thickness[0.005]}, {Black, 
    Thickness[0.005]}},
 ImageSize -> 400,
 ScalingFunctions -> {"Reverse", Identity}
]

Example of manually adding frame ticks to plot.

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

I ended up using my custom ticks function for the left and right sides because Mathematica always shrinks my tick marks when I export (which is the reason I so often have to create my own ticks). This has the added benefit of making sure all the tick marks are the same length, but you could easily leave the left and right sides as Automatic if you like.

$\endgroup$

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