3
$\begingroup$

I'm trying to use Graphics Column to add a label under my plots. Eventually these individual columns will be combined in a grid, and I want the height of each plot to be the same so I can compare data easily. My problem is this: when the column ImageSize is such that the bottom label is multi line, it doesn't display properly. Can I tell Graphics Column to be sure to add enough room that all of the text can be seen?

Examples: This code cuts off the label text at the bottom:

toPlot = {{{1, 0.024017467248908332`}, {1, 
     0.`}, {1, -0.07205240174672484`}}, {{2, 
     0.048034934497816664`}, {2, 0.09170305676855903`}, {2, 
     0.06986899563318784`}}, {{3, 0.2227074235807861`}, {3, 
     0.13537117903930138`}, {3, 0.13537117903930138`}}};
dataSetList = {"data set #1 is called a", "data set #2 is called b", 
   "data set #3 is called c"};

GraphicsColumn[{ListPlot[toPlot,
   Frame -> True,
   PlotLabel -> "This is the label for the plot"
   ],
  Style[StringJoin["Data sets included: ", 
    StringRiffle[dataSetList, ", "]], "SmallText"]},
 ImageSize -> Medium,
 Frame -> True]

Multiline text not displaying correctly

Same code, force the ImageSize to Large, and it works as desired:

toPlot = {{{1, 0.024017467248908332`}, {1, 
     0.`}, {1, -0.07205240174672484`}}, {{2, 
     0.048034934497816664`}, {2, 0.09170305676855903`}, {2, 
     0.06986899563318784`}}, {{3, 0.2227074235807861`}, {3, 
     0.13537117903930138`}, {3, 0.13537117903930138`}}};
dataSetList = {"data set #1 is called a", "data set #2 is called b", 
   "data set #3 is called c"};

GraphicsColumn[{ListPlot[toPlot,
   Frame -> True,
   PlotLabel -> "This is the label for the plot"
   ],
  Style[StringJoin["Data sets included: ", 
    StringRiffle[dataSetList, ", "]], "SmallText"]},
 ImageSize -> Large,
 Frame -> True]

Bottom label displays correctly

Thank you for any advice!

$\endgroup$

2 Answers 2

4
$\begingroup$

I put your text in a TextCell with a limited x-direction size.

GraphicsColumn[{ListPlot[toPlot, Frame -> True, 
   PlotLabel -> "This is the label for the plot"], 
  TextCell[
   Style[
    StringJoin["Data sets included: ", 
     StringRiffle[dataSetList, ", "]], "SmallText"], 
   CellSize -> {300, Automatic}, TextAlignment -> Center]}, 
 ImageSize -> Automatic, Frame -> True]
$\endgroup$
2
  • $\begingroup$ Seems you beat me with a significantly shorter solution. Nice! You could also use Pane[..., 300, Alignment->Center] instead of the TextCell, but I'm not sure which one I prefer $\endgroup$
    – Lukas Lang
    Aug 8, 2022 at 22:35
  • $\begingroup$ I like this! It works at a wider variety of sizes, though the odd behavior of cutting of the top and bottom of the text persists as the graph gets really small. Still, this seems to do what I need. $\endgroup$ Aug 10, 2022 at 16:04
1
$\begingroup$

I am not aware of any method to actively control the size of individual rows/columns in GraphicsGrid and friends (I am already surprised that the row containing text is sized as it is). [Edit: See @Jean-Pierre's answer for a nice and simple way to get GraphicsColumn to deduce the correct row height]

You may be able to achieve your goals using ResourceFunction["PlotGrid"]:

toPlot = {{{1, 0.024017467248908332`}, {1, 
     0.`}, {1, -0.07205240174672484`}}, {{2, 
     0.048034934497816664`}, {2, 0.09170305676855903`}, {2, 
     0.06986899563318784`}}, {{3, 0.2227074235807861`}, {3, 
     0.13537117903930138`}, {3, 0.13537117903930138`}}};
dataSetList = {"data set #1 is called a", "data set #2 is called b", 
   "data set #3 is called c"};

    Framed@ResourceFunction["PlotGrid"][
     {
      {
       ListPlot[toPlot, Frame -> True, 
        PlotLabel -> "This is the label for the plot"]
       }, {
       Graphics@Inset[
         Style[
          StringJoin["Data sets included: ", 
           StringRiffle[dataSetList, ", "]], "SmallText"],
         Automatic, Automatic, Scaled@{1, 1}
         ]
       }
      },
     ItemSize -> {1, {1, Offset[50]}},
     Spacings -> 15
     ]

enter image description here

Some notes:

  • I am using Framed for the outer frame since PlotGrid doesn't support this kind of frame natively.
  • PlotGrid always expects a 2D matrix of plots, so I am giving it a column vector {{...}, {...}}
  • PlotGrid expects graphics, so I wrapped the text in Graphics[Inset[...,Automatic,Automatic,Scaled@{1,1}]]. This produces a graphics with only your text centered in the middle, auto-wrapping lines as necessary
  • The height of the row must be specified manually, which I am doing using ItemSize -> {1, {1, Offset[50]}}. This sets the columns to all have the same size (you only have one). The second row (via Offset[50]) is set to a fixed height of 50 printers points, while the first row will fill up the remaining space.
  • Spacings->15 ensures there is space for the bottom frame labels of the plot
$\endgroup$

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.