10
$\begingroup$

Consider the following grid

n = 10;
Grid[{{"Matrix", SpanFromLeft},
  RandomInteger[n, n], RandomInteger[n, n]},
 Frame -> All, Alignment -> Center]

enter image description here

Is there any "clever" way of getting the following layout

enter image description here

so that the length of the "backline" is always adjusted according to n

enter image description here

and, without the main frame, I'd get

enter image description here

I know about FontVariations and though about using "StrikeThrough" over an empty string, but couldn't make it work. Maybe customizing a divider's position? Any ideas?

Edit: going one step further, what about something like

enter image description here

$\endgroup$

2 Answers 2

12
$\begingroup$

ItemSize >> Properties and Relations:

  • "Controls and graphics will by default expand to fit the available area."

So we can use a graphics object as the title row:

ClearAll[addTitleRow]
addTitleRow[ttl_,  lineStyle_: Automatic, textStyle_: Automatic, pos_: {.5, 0}] :=
   PadRight[
     Prepend[{Graphics[{lineStyle /. 
            Automatic -> Directive[Gray, Thickness[Tiny]], Line[{{0, 0}, {1, 0}}],
          Black, Text[Style[ttl, textStyle /. Automatic -> 14, 
            Background -> White], pos]}, 
        ImagePadding -> 0, PlotRangePadding -> 0, 
        ImageSize -> {Scaled[1.03], All}, AspectRatio -> 1/20]}] @ #, 
     Automatic, SpanFromLeft] &;

Examples:

n = 10;
mat = {RandomInteger[n, n], RandomInteger[n, n]};

Grid[addTitleRow["  matrix  "] @ mat, 
 Alignment -> {Center, Center}, ItemSize -> {3, 1}, Frame -> All]

enter image description here

Grid[addTitleRow["  matrix  "] @ mat, 
  Alignment -> {Center, Center}, ItemSize -> {3, 1}, Frame -> {True, {False, {True}}}]

enter image description here

Grid[addTitleRow["  matrix  "] @ mat,  
  Alignment -> {Center, Center}, ItemSize -> {3, 1}]

enter image description here

Grid[addTitleRow["  matrix  ", 
   Directive[Orange, AbsoluteThickness[12], CapForm["Butt"]], 
   Directive[Blue, 18], {.15, 0}] @ mat, 
 Alignment -> {Center, Center}, ItemSize -> {3, 1}, Frame -> All]

enter image description here

Replace Frame -> All with Frame -> {True, {False, {True}}} to get

enter image description here

Remove the option Frame -> .. to get

enter image description here

mat2 = {RandomInteger[n, 2 n], RandomInteger[n, 2 n]};

Grid[addTitleRow["  matrix  "] @ mat2, 
 Alignment -> {Center, Center}, ItemSize -> {2, 1}, Frame -> All]

enter image description here

$\endgroup$
2
  • $\begingroup$ Brilliant answer, this is exactly what I'm looking for. I just noticed that the "matrix" row's height scales with n. Any easy fix for this? $\endgroup$
    – sam wolfe
    Commented Jul 8, 2021 at 11:49
  • $\begingroup$ @samwolfe, maybe changing ImageSize->.. to ImageSize -> {Scaled[1.03], Scaled[1]} and AspectRatio ->.. to AspectRatio -> Dimensions[#][[1]]/(4 Dimensions[#][[2]])? $\endgroup$
    – kglr
    Commented Jul 8, 2021 at 15:14
8
$\begingroup$

A first thought of how approach the problem.

n = 10;
itemSize = 1.5;
Column[{
  Grid[{
    {"", " Matrix ", ""},
    {"", SpanFromAbove, ""}
    },
   Frame -> All,
   ItemSize -> n/itemSize,
   Alignment -> {Center, Center},
   Dividers -> {False, {False, {2 -> True}}}],
  
  Grid[{
    RandomInteger[n, n],
    RandomInteger[n, n]},
   ItemSize -> itemSize,
   Frame -> None,
   Alignment -> Center]
  },
 Alignment -> Center]

enter image description here

I set up a Column of 2 Grids.

The first, Grid enables you to center your label, "Matrix", and to generate horizontal lines to each side of it using Grid's option, Dividers.

I've set up a variable itemSize = 1.5 and use it in the 2nd Grid to establish a known fixed width for each column in the 2nd Grid.

In the 1st Grid, I set a simple relationship between your n and the 1st Grid's ItemSize option.

You could certainly do this more elegantly and more comprehensively. This works on my machine with n >= 7, but it would benefit from more thought.

Essentially:

  • breakup the problem into smaller bits.
  • control things that matter (e.g., ItemSize->n/itemSize).
  • establish a relationship between the smaller bits.

If the above looks promising, you could try controlling the ItemSize in the 1st Grid for each of its 3 columns.

$\endgroup$
1
  • $\begingroup$ Thanks! I noticed that there is some offset on those dividers for some big enough n. Interesting approach nonetheless. Maybe I can work around that somehow. $\endgroup$
    – sam wolfe
    Commented Jul 8, 2021 at 11:51

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.