2
$\begingroup$

I am producing some plots with legends on Mathematica, using PlotLegends.

For aesthetical reasons, I was wondering if there was a simple way to impose to a legend placed above a plot to be horizontally centered with respect to the plot's frame. The default behaviour seems rather to have it horizontally centerd with respect to the full figure (which includes axes labels), which can sometimes induce a visual feeling of ill-alignment.

Here is an exagerated example of the behaviour that I am trying to avoid :

P1 = Plot[{Sin[3 \[Theta] + 1], Cos[\[Theta]]}, {\[Theta], 0, 2 \[Pi]}, Frame -> True, 
  FrameTicksStyle -> Directive[FontSize -> 16], 
  PlotLegends -> Placed["Expressions", {Center, Above}], 
  FrameLabel -> {Style["\[Theta]", 25], Style["|\[CapitalPsi]|", 25]}]

with outcome

enter image description here

The legends are not centered with respect to the frame, but with respect to the frame+labels of the axes, which makes them appear too much left with respect to the frame.

The centering result that I would seek for the same example is that of PlotLabel, which centers the text with respect to the frame:

P2 = Plot[{Sin[3 \[Theta] + 1], Cos[\[Theta]]}, {\[Theta], 0, 2 \[Pi]}, Frame -> True, 
  FrameTicksStyle -> Directive[FontSize -> 16], 
  PlotLabel -> "--- sin(3\[Theta]+1)          --- cos(\[Theta])", 
  FrameLabel -> {Style["\[Theta]", 25], Style["|\[CapitalPsi]|", 25]}]

with outcome

enter image description here

Obviously PlotLabel is not suitable for legending, but I am looking for a legending option that offers a final legend alignment similar to it.

$\endgroup$

1 Answer 1

2
$\begingroup$

Instead of using: Placed["Expressions", {Center, Above}] use a scaled coordinate for the x placement like:

Plot[{Sin[3 \[Theta] + 1], Cos[\[Theta]]}, {\[Theta], 0, 2 [Pi]}, 
 Frame -> True, FrameTicksStyle -> Directive[FontSize -> 16], 
 PlotLegends -> Placed["Expressions", {0.6, Above}], 
 FrameLabel -> {Style["\[Theta]", 25], Style["|\[CapitalPsi]|",25]}]

enter image description here

Addendum

If you do not want to use a scaled coordinate, you can use the following hack:

-Create a plot without a plot label

-Use "Show" to add a plot label

p0 = Plot[{Sin[3 \[Theta] + 1], Cos[\[Theta]]}, {\[Theta], 0, 
    2 \[Pi]}, Frame -> True, 
   FrameTicksStyle -> Directive[FontSize -> 16], 
   FrameLabel -> {Style["\[Theta]", 25], 
     Style["|\[CapitalPsi]|", 25]}];
Show[p0, 
 PlotLabel -> "--- sin(3\[Theta]+1)          --- cos(\[Theta])"]

enter image description here

$\endgroup$
6
  • $\begingroup$ Many thanks for the reply! What I would ideally be looking for is to have something robust with respect to (more or less) any plot. By this I mean not having to go through trial and error to find which value to use (here 0.6) instead of the Center argument. Is there any way to do so? For example gathering the various relevant widths in the figure and from these build a function which provides the right offset for the legend placement ? $\endgroup$
    – Düdzi
    Oct 12, 2022 at 13:35
  • $\begingroup$ I added a hack for this to my answer. $\endgroup$ Oct 12, 2022 at 14:33
  • $\begingroup$ I think there is a misunderstanding here, seeing your Addendum. My question is about having a legend properly centered with respect a plot's frame in an "automatized" way, I do not want to have a PlotLabel. I mentioned PlotLabel because I found out that the latter's default centering is precisely the centering that I am looking for. From this I concluded that, in the background, Mathematica knows of a way to automatically handle the centering that I wish. I am trying to find a way to make this centering result apply to legends. $\endgroup$
    – Düdzi
    Oct 12, 2022 at 14:58
  • $\begingroup$ By "automatized" I mean something that does not require to find manually a scaling through trial and error $\endgroup$
    – Düdzi
    Oct 12, 2022 at 14:59
  • $\begingroup$ Users need options like AboveFrame and BelowFrame. $\endgroup$
    – Syed
    Oct 12, 2022 at 15:07

Your Answer

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

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