1
$\begingroup$

I've seen other questions around here and on the forum on Mathematica but none of them worked for me. The question is the same: how can I extract the ticks from the plot in order to not overlap to the plot? I've tried lot of the solutions proposed here, but none of them seemed to work for me. Maybe I could have wrongly interpreted the information.

Could somebody help me getting the ticks outside the plot?

DensityPlot[x, {x, 380, 780}, {y, 0, 1}, 
  ColorFunction -> "Rainbow", 
  AspectRatio -> 1/8, 
  PlotRangePadding -> None,
  FrameTicks -> Automatic]

enter image description here

Just to make clear I add a simple plot of a Sine to clarify what i mean by saying that the ticks are "inside the plot", while I want them outside, anyway if you take a look to the previous question you'll find even some solution for the case of a normal plot... enter image description here Regarding the answer, by scaling the image I get this bad-looking effect... enter image description here

$\endgroup$
3
  • 1
    $\begingroup$ @opisthofulax Apologies for my naive answer. I deleted it. Have you tried DensityPlot[x, {x, 380, 780}, {y, 0, 1}, ColorFunction -> "Rainbow", AspectRatio -> 1/8, PlotRangePadding -> None, FrameTicks -> Out]?? I am asking as I cannot see the ticks. Cheers!!! $\endgroup$
    – user49048
    Commented Mar 15, 2018 at 23:57
  • $\begingroup$ Out seems not to be a valid options for FrameTicks , ad Mathematica gives me an error if i plug it in... $\endgroup$ Commented Mar 15, 2018 at 23:58
  • $\begingroup$ The ticks are very small, but inside the picture, if you make whatever plot you want on Mathematica you'll get ticks on the inner part of the frames or the axes $\endgroup$ Commented Mar 15, 2018 at 23:59

1 Answer 1

8
$\begingroup$

Perhaps you mean something like:

DensityPlot[
    x,
    {x,380,780},
    {y,0,1},
    ColorFunction->"Rainbow",
    AspectRatio->1/8,
    PlotRangePadding->None,
    FrameTicks->{
        {Charting`ScaledTicks[{Identity,Identity}, "TicksLength"->{-.01,-.005}],None},
        {Charting`ScaledTicks[{Identity,Identity}, "TicksLength"->{-.01,-.005}],None}
    }
]

enter image description here

where I used negative tick lengths.

Addendum

In my original answer, I basically used a negative number for the "positive" tick length. This is a problem because the tick label position only depends on the "negative" tick length. It would have been better to use the documented syntax:

$$\left\{\left\{x_1,\operatorname{label}_1,\left\{\operatorname{plen}_1,\operatorname{mlen}_1\right\}\right\},\ldots \right\}$$

instead, i.e., {0, .01} instead of {-.01, 0}. In fact, using the documented syntax avoids the label/tick collision as long as the AspectRatio is 1. For example, compare:

GraphicsRow[{
    Graphics[
        {},
        PlotRange->{{0,100},{0,10}},
        AspectRatio->1,
        Frame->True,
        FrameTicks->{{None,None},{{{10, 10, {0, .2}}},None}}
    ],
    Graphics[
        {},
        PlotRange->{{0,100},{0,10}},
        Frame->True,
        FrameTicks->{{None,None},{{{10, 10, {0, .2}}},None}}
    ]
}]

enter image description here

Another possible approach to avoid the label/tick collision is to use a plot range that has an aspect ratio of 1:

GraphicsRow[{
    Graphics[
        {},
        PlotRange->{{380, 780}, {0, 400}},
        Frame -> True,
        FrameTicks -> {{None, None}, {{{400, 400, {0, .2}}}, None}},
        AspectRatio -> Full,
        ImageSize -> {300, 40}
    ],
    Graphics[
        {},
        PlotRange->{{380, 780}, {0, 400}},
        Frame -> True,
        FrameTicks -> {{None, None}, {{{400, 400, {0, .5}}}, None}},
        AspectRatio -> Full,
        ImageSize -> {300, 40}
    ]
}]

enter image description here

So, here's a function that leverages Charting`ScaledTicks, but adds support for custom tick lengths:

Options[customTicks] = Options[Charting`ScaledTicks];

customTicks[args__, opts:OptionsPattern[]][rng__] := Module[{major, minor},
    Internal`InheritedBlock[{Charting`ScaledTicks},
        Unprotect[Charting`ScaledTicks];
        SetOptions[Charting`ScaledTicks, "TicksLength"->{1, 2}];
        {major, minor} = Replace[
            OptionValue[customTicks, "TicksLength"],
            Except[{_, _}] :> {{.01, 0.}, {.005, 0.}}
        ];
        major = Replace[major,
            {
            t_?NumericQ :> {t, 0.},
            Except[{_, _}] :> {.01, 0.}
            }
        ];
        minor = Replace[minor,
            {
            t_?NumericQ :> {t, 0.},
            Except[{_, _}] :> {.005, 0.}
            }
        ];      
        Replace[
            Charting`ScaledTicks[args, "TicksLength"->Automatic, opts][rng],
            {
                {a_, b_, {1, 0.}, c___} :> {a, b, major, c},
                {a_, b_, {2, 0.}, c___} :> {a, b, minor, c}
            },
            {1}
        ]
    ]
]

Using customTicks for your density plot:

GraphicsRow[{
    DensityPlot[
        x,
        {x,380,780},
        {y,0,400},
        PlotRangePadding->None,
        ColorFunction->"Rainbow",
        FrameTicks->{
            {None, None},
            {customTicks["Linear", "TicksLength"->{{0, .2}, {0, .1}}], None}
        },
        AspectRatio->Full,
        ImageSize->Automatic->{240, 30}
    ],
    DensityPlot[
        x,
        {x,380,780},
        {y,0,400},
        PlotRangePadding->None,
        ColorFunction->"Rainbow",
        FrameTicks->{
            {None, None},
            {customTicks["Linear", "TicksLength"->{{0, .4}, {0, .2}}], None}
        },
        AspectRatio->Full,
        ImageSize->Automatic->{240, 30}
    ]
}]

enter image description here

$\endgroup$
2
  • $\begingroup$ That's really what I was looking for, but I have a little problem when I try to scale the picture: the ticks keep growing but not their labels, also the distance between them does not change, so eventually they overlap... $\endgroup$ Commented Mar 16, 2018 at 0:16
  • $\begingroup$ That is what I call an answer, I'll try as soon as possible and give you best answer, thanks so much. $\endgroup$ Commented Mar 16, 2018 at 10:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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