Skip to main content

plotting - Display frame-tick labels on top side


I am making a standard framed Plot and would like the frame tick labels for the horizontal axis to appear on the top frame edge.



I know I can do this by hand using, for example:


Plot[x, 
{x, 0, 5},
Frame -> True,
FrameTicks -> {{Automatic,
Automatic}, {{{0, ""}, {1, ""}, {2, ""}, {3, ""}, {4, ""}, {5,
""}}, {0, 1, 2, 3, 4, 5}}}
]

But that is so terribly cumbersome, how can I just make the standard/default frame ticks appear on the top instead of the bottom?




Answer



It's a hack, but this should work:


Plot[x, {x, 0, 5}, Frame -> True, 
FrameTicks -> {{Automatic, Automatic}, {Automatic, All}},
ImagePadding -> {{20, 20}, {4, 20}}]

imagemargins


The values for ImagePadding are chosen so as to leave no room for the bottom tick labels to be displayed. You can change the margins from 20 to 40 (e.g.) if you need more room to display additional labels. The bottom image margin of 4 is the one that cuts off the undesired labels.


Edit: a more systematic approach


The following approach is based on a different idea that will not require any devious cropping of unwanted text. At the same time, it still avoids the need to specify tick marks manually.



To achieve this, I use FindDivisions to emulate the Automatic tick placement (I didn't try to get it exactly right, but added some customizability). The ticks are calculated automatically for each plot, and there are versions with and without tick labels: tickFunction and tickFunctionNoLabel. To avoid having to think about these functions every time you make a plot, I just use SetOptions to make Plot call them automatically:


Clear[tickFunction, tickFunctionNoLabel, gridFunction, divisionFunction]

divisionFunction[xMin_, xMax_] :=
FindDivisions[{xMin, xMax}, {8, 5}];

gridFunction[xMin_, xMax_] := First[divisionFunction[xMin, xMax]]

Options[tickFunction] = {"MinorLength" -> 0.005, "MajorLength" -> .01,
"InsideOutside" -> {1, 0}};


tickFunction[xMin_, xMax_, OptionsPattern[]] :=
Module[{major, minor},
{major, minor} = divisionFunction[xMin, xMax];
Join[Map[{#, #,
OptionValue["InsideOutside"] OptionValue["MajorLength"]} &,
major], Map[{#, "",
OptionValue["InsideOutside"] OptionValue["MinorLength"]} &,
Flatten[minor[[All, 2 ;; -2]]]]]
]


tickFunctionNoLabel[xMin_, xMax_] :=
Map[{#[[1]], "", #[[-1]]} &, tickFunction[xMin, xMax]]

SetOptions[Plot,
FrameTicks ->
{{tickFunction, tickFunctionNoLabel}, {tickFunctionNoLabel, tickFunction}}];

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


tickfunction


As you see, I didn't have to add any options to this Plot command, and the frame ticks come out properly.


I added the ability to adjust the lengths of the major and minor ticks as options of the tickFunction. Another option is called "InsideOutside" which decides how much of the ticks is inside or outside of the frame. By default, it's all inside, specified by an option value {1,0}. Here is what it looks like with external ticks:


SetOptions[tickFunction, "InsideOutside" -> {0, 1}];

Plot[x, {x, 0, 5}, Frame -> True,
GridLines -> gridFunction]

grid


For fun, I added a grid to this plot (that's when you really need external ticks, I think). The grid is derived from the same FindDivisions that underlies the ticks, as calculated in divisionFunction.



In this approach, the placement of the labels is entirely controlled by the order in which you call tickFunction or tickFunctionNoLabel in the FrameTicks option specification.


For example, you can do the following:


SetOptions[Plot, 
FrameTicks -> {{tickFunctionNoLabel,
tickFunction}, {tickFunctionNoLabel, tickFunction}}];

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

right label


Finally, an example for different tick lengths, where I also choose to specify the tick functions directly as an option in Plot:



SetOptions[tickFunction, "InsideOutside" -> {1, 0}, 
"MajorLength" -> .02, "MinorLength" -> .01];

Plot[x, {x, 0, 5}, Frame -> True,
FrameTicks -> {{tickFunction, tickFunction}, {tickFunctionNoLabel,
tickFunction}}]

tick lengths


To further customize the automatic tick marks, you can also change the parameters of FindDivisions in the definition of divisionFunction.


Comments

Popular posts from this blog

plotting - Plot 4D data with color as 4th dimension

I have a list of 4D data (x position, y position, amplitude, wavelength). I want to plot x, y, and amplitude on a 3D plot and have the color of the points correspond to the wavelength. I have seen many examples using functions to define color but my wavelength cannot be expressed by an analytic function. Is there a simple way to do this? Answer Here a another possible way to visualize 4D data: data = Flatten[Table[{x, y, x^2 + y^2, Sin[x - y]}, {x, -Pi, Pi,Pi/10}, {y,-Pi,Pi, Pi/10}], 1]; You can use the function Point along with VertexColors . Now the points are places using the first three elements and the color is determined by the fourth. In this case I used Hue, but you can use whatever you prefer. Graphics3D[ Point[data[[All, 1 ;; 3]], VertexColors -> Hue /@ data[[All, 4]]], Axes -> True, BoxRatios -> {1, 1, 1/GoldenRatio}]

plotting - Filling between two spheres in SphericalPlot3D

Manipulate[ SphericalPlot3D[{1, 2 - n}, {θ, 0, Pi}, {ϕ, 0, 1.5 Pi}, Mesh -> None, PlotPoints -> 15, PlotRange -> {-2.2, 2.2}], {n, 0, 1}] I cant' seem to be able to make a filling between two spheres. I've already tried the obvious Filling -> {1 -> {2}} but Mathematica doesn't seem to like that option. Is there any easy way around this or ... Answer There is no built-in filling in SphericalPlot3D . One option is to use ParametricPlot3D to draw the surfaces between the two shells: Manipulate[ Show[SphericalPlot3D[{1, 2 - n}, {θ, 0, Pi}, {ϕ, 0, 1.5 Pi}, PlotPoints -> 15, PlotRange -> {-2.2, 2.2}], ParametricPlot3D[{ r {Sin[t] Cos[1.5 Pi], Sin[t] Sin[1.5 Pi], Cos[t]}, r {Sin[t] Cos[0 Pi], Sin[t] Sin[0 Pi], Cos[t]}}, {r, 1, 2 - n}, {t, 0, Pi}, PlotStyle -> Yellow, Mesh -> {2, 15}]], {n, 0, 1}]

plotting - Mathematica: 3D plot based on combined 2D graphs

I have several sigmoidal fits to 3 different datasets, with mean fit predictions plus the 95% confidence limits (not symmetrical around the mean) and the actual data. I would now like to show these different 2D plots projected in 3D as in but then using proper perspective. In the link here they give some solutions to combine the plots using isometric perspective, but I would like to use proper 3 point perspective. Any thoughts? Also any way to show the mean points per time point for each series plus or minus the standard error on the mean would be cool too, either using points+vertical bars, or using spheres plus tubes. Below are some test data and the fit function I am using. Note that I am working on a logit(proportion) scale and that the final vertical scale is Log10(percentage). (* some test data *) data = Table[Null, {i, 4}]; data[[1]] = {{1, -5.8}, {2, -5.4}, {3, -0.8}, {4, -0.2}, {5, 4.6}, {1, -6.4}, {2, -5.6}, {3, -0.7}, {4, 0.04}, {5, 1.0}, {1, -6.8}, {2, -4.7}, {3, -1....