24
$\begingroup$

By default Mathematica places the x-axis labels at the end of the axes likeenter image description here

Googling has suggested a way around this is to use Frame- for example Frame -> {True, True, False, False}, FrameLabel -> {"E/T", None} which produces something like enter image description here

Which is not too bad, but I do not want this vertical dividing line x=0 and really would have preffered to keep the y-axis in the middle of the plot where this divider line now is. Can this be done? Is there a better way than this to move axes labels below?

$\endgroup$
19
$\begingroup$

Which is not too bad, but I do not want this vertical dividing line $x = 0$ and really would have preferred to keep the $y$-axis in the middle of the plot where this divider line now is.

An easy way is to use Labeled with Plot since Plot keeps the y axis in the middle while Frame->True moves it to the left where you do not want it.

Labeled[Plot[Sin[x] x, {x, -3, 3}], "E/T"]

enter image description here

Labeled has many option to allow different placements and alignments and such, so it can actually be used instead of the plot labeling. The only thing to keep in mind, is that symbols used in inside the Plot, such as those used by PlotLabel are automatically set in TraditionalMode while those set by Labeled are not and you have to do that yourself if you want that typesetting. Compare the typesetting below on the labels:

Grid[{

  {Labeled[Plot[Sin[x] x, {x, -3, 3}, ImageSize -> 300],Sin[x]]},

  {Plot[Sin[x] x, {x, -3, 3},AxesLabel->{Sin[x],None},ImageSize->300]}

 }, Frame -> All
]

enter image description here

But this is easy to handle. Simply use TraditionalForm for `Labeled, like this

Clear[x];

Labeled[Plot[Sin[x] x, {x, -3, 3}, ImageSize -> 300], 

 Text@TraditionalForm@Style[Sin[x], 16]

]

enter image description here

edit To answer the comment about exporting;

I just saved the image using Save Selection as eps, and labels are there

enter image description here

I am on Linux, and Export in the version of Mahematica I am using is not supported. But it seems to save .eps just fine.

$\endgroup$
  • 1
    $\begingroup$ thanks, that works pretty well. I didn't mention in my OP but I actually have three plots that I usually show on the same axis using Show[plot1,plot2,plot3] -with your method if I do Show[ Labeled[Plot[Sin[x] x, {x, -3, 3}], "E/T"],Labeled[Plot[Cos[x] x, {x, -3, 3}], "E/T"]] for example then things don't seem to work. Is there a way to get around this? $\endgroup$ – fpghost Jan 14 '13 at 12:14
  • 1
    $\begingroup$ Actually I see now that Labeled[Show[plot1, plot2, plot3], "E/T", LabelStyle -> Directive[20, Bold]] works fine. Thanks again. $\endgroup$ – fpghost Jan 14 '13 at 12:18
  • 1
    $\begingroup$ If one then exports this figure as an eps say the axes labels do not seem to get exported too? $\endgroup$ – fpghost Jan 14 '13 at 12:22
  • 1
    $\begingroup$ Sorry my mistake again- the problem was I was simply doing `Right-click>Export' rather than the command version which gave the desired behaviour. $\endgroup$ – fpghost Jan 14 '13 at 12:46
24
$\begingroup$
  Plot[Sin[x] x, {x, -3, 3}, Frame -> {True, True, False, False}, 
   FrameLabel -> {"E/T", None}, Axes -> False]

enter image description here

$\endgroup$
  • 1
    $\begingroup$ Note that the axis now sits away from (-3,0) by a small margin. Do you know how to set it exactly at (-3,0)? $\endgroup$ – Corvus Mar 26 '15 at 23:11
  • 5
    $\begingroup$ @Corvus, you can use the option PlotRangePadding -> 0. $\endgroup$ – kglr Mar 26 '15 at 23:14
  • 2
    $\begingroup$ You're amazing - answering a two year old post in under 5 minutes - thank you!! $\endgroup$ – Corvus Mar 26 '15 at 23:20
2
$\begingroup$

Using Labeled can be suboptimal because the location of the label along the horizontal axis can only be set to Left, Center or Right. If the vertical axis ticks are large, then none of these positions is truly satisfactory. For instance:

bar = BarChart[Range[4], BarOrigin->Left, ChartLabels->{aaaaaaaaaaaaa, b, c, d}];
Labeled[
    bar,
    "x-axis",
    {{Bottom, Center}}
]

enter image description here

One might wish to place the "x-axis" label centered at ~2.1 instead of ~1.6.

Using FrameLabel instead is a possibility, but sometimes (as in this question), the axes origin does not coincide with the lower left corner.

So, below I will present 3 other possibilities. All of these approaches need to gather some information about the plot using the function GraphicsInformation, a function given in my answer to Retrieving the ImagePadding in absolute units. This function is now a paclet, and can be installed and loaded with:

PacletInstall[
    "GraphicsInformation",
    "Site"->"http://raw.githubusercontent.com/carlwoll/GraphicsInformation/master"
];

<<GraphicsInformation`

Ticks

The first option is to include the label using the Ticks option. To do this we first need to obtain the ticks using AbsoluteOptions (I need to change the plot range because AbsoluteOptions doesn't like the default PlotRange for BarChart):

ticks = OptionValue[
    AbsoluteOptions[Show[bar, PlotRange->OptionValue[GraphicsInformation[bar], "PlotRange"]]],
    Ticks
];

To add a label centered at 2.1, we just prepend a tick:

newticks = Replace[ticks, {a_, b_} :> {Prepend[a, {2.1, Underscript["", Style["x-axis", 14]], 0}], b}];
Show[bar, Ticks -> newticks]

enter image description here

The downside to this approach is the need to figure out the ticks, and you will notice that the ticks returned by AbsoluteTicks use decimals.

Epilog

The second option is to use Epilog and adjust the ImagePadding. To do this we first need to find the old ImagePadding:

old = OptionValue[GraphicsInformation[bar], "ImagePadding"]

{{68.1939, 1.5}, {13.4116, 2.84217*10^-14}}

Then, we place the "x-axis" label using a Text directive in an Epilog:

Show[
    bar,
    Epilog->Text[Style["x-axis", 14], Offset[{0, -15}, {2.1, 0}], {0, 1}],
    ImagePadding -> old + {{0, 0}, {20, 0}}
]

enter image description here

The Offset[{0, -15}, {2.1, 0}] argument places the label at the position {2.1, 0} in plot coordinates, then moves the label lower by 15 points. The ImagePadding is adjusted so that the label is included in the plot. The downside to this approach is that the option PlotRangeClipping->False must be used, otherwise the epilog will not be displayed.

Inset

The final option is to use Inset to place the plot inside of a graphics object that can contain other elements (like an x-axis label). With this approach, we don't need to worry about the PlotRangeClipping option. To do this, we will need to know some information about the bar chart using GraphicsInformation. One needed tweak is to set the axes origin back to {0,0}:

{pad, size, pr, prsize} = OptionValue[
    GraphicsInformation[Show[bar, AxesOrigin->{0, 0}]],
    {"ImagePadding", "ImageSize", "PlotRange", "PlotRangeSize"}
];

The above information can be used to create the following Graphics object:

Graphics[
    {
    Inset[
        Show[bar, ImagePadding->pad, AxesOrigin->{0, 0}],
        {0, 0},
        {0, 0},
        Offset[size]
    ],
    Text[Style["x-axis", 14], Offset[{0, -15}, {2.1, 0}], {0, 1}]
    },
    PlotRange->pr,
    ImagePadding->pad + {{0, 0}, {10, 0}},
    ImageSize->Automatic->prsize
] 

enter image description here

The ImagePadding option in the Inset shouldn't be necessary, but unfortunately there appears to be a bug in GraphicsInformation.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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