Function Repository Resource:

CharacterArrayPlot

Source Notebook

Decorate an ArrayPlot with additional characters

Contributed by: Bradley Klee

ResourceFunction["CharacterArrayPlot"][array]

generates an ArrayPlot of array and overlays values as textual symbols.

Details

ResourceFunction["CharacterArrayPlot"] takes all the arguments of Graphics, and a few more:
ColorRuleshow to assign colors to array values
CharacterRuleshow to assign characters to array values
CharacterStyleRuleshow to assign styles to array values
Mesha boolean value for adding a border to cells
MeshStylehow to style borders when Mesh is True
ColorRules behaves similarly to the standard ArrayPlot option.
CharacterRules should be a list where each element is a rule mapping between an array value and a string character.
CharacterStyleRules should be a list where each element is a rule mapping between an array value and a list of stylistic attributes.
Stylistic attributes get fed into Style as a sequence following the first argument of a chosen textual character.
ColorRules, CharacterRules, and CharacterStyleRules also accept mixed lists containing Rule and RuleDelayed elements.

Examples

Basic Examples (3) 

Plot a numerical 2×2 array with colors and numbers:

In[1]:=
ResourceFunction["CharacterArrayPlot"][{{1, 2}, {3, 4}}, ImageSize -> 100]
Out[1]=

Adjust GrayLevel values and font sizes:

In[2]:=
ResourceFunction["CharacterArrayPlot"][{{1, 2}, {3, 4}},
 ColorRules -> {x_ :> GrayLevel[(x + 4)/8]},
 "CharacterStyleRules" -> {x_ :> {36, Black}},
 MeshStyle -> Black, ImageSize -> 100]
Out[2]=

Exchange numbers for letters:

In[3]:=
ResourceFunction["CharacterArrayPlot"][{{1, 2}, {3, 4}},
 ColorRules -> {x_ :> GrayLevel[(x + 4)/8]},
 "CharacterStyleRules" -> {x_ :> {36, Black}},
 "CharacterRules" -> {1 -> "A", 2 -> "B", 3 -> "C", 4 -> "D"},
 MeshStyle -> Black, ImageSize -> 100]
Out[3]=

Add colors:

In[4]:=
ResourceFunction["CharacterArrayPlot"][{{1, 2}, {3, 4}},
 ColorRules -> {x_ :> Lighter[Hue[(x + 1)/6], .6]},
 "CharacterStyleRules" -> {x_ :> {36, Lighter[Hue[(6 - x)/6], .6]}},
 "CharacterRules" -> {1 -> "A", 2 -> "B", 3 -> "C", 4 -> "D"},
 MeshStyle -> Directive[Gray, Thick], ImageSize -> 100]
Out[4]=

Plot a position in a game of tic-tac-toe, player X to win:

In[5]:=
ResourceFunction[
 "CharacterArrayPlot"][{{1, 2, 0}, {2, 0, 0}, {1, 0, 1}},
 ColorRules -> {0 -> White, 1 -> Lighter[Orange, .5],
   2 -> Lighter[Purple, .7]},
 "CharacterStyleRules" -> {x_ :> {26, Black, Bold}},
 "CharacterRules" -> {1 -> "X", 2 -> "O", 0 -> ""},
 MeshStyle -> Directive[Thick, LightGray],
 ImageSize -> 100, Frame -> True, FrameTicks -> False,
 FrameStyle -> Directive[
   Blend[{Orange, Red}, .3], Thickness[.05]]]
Out[5]=

Make an even larger plot of randomly-sampled letters:

In[6]:=
ResourceFunction["CharacterArrayPlot"][Partition[
  RandomChoice[ToUpperCase /@ Alphabet[], 169], 13],
 ImageSize -> 500]
Out[6]=

Scope (2) 

CharacterArrayPlot is designed to work well with FromCharacterCode:

In[7]:=
With[{chessBoard = MapIndexed[
    If[Mod[Total[#2], 2] == 0, #1, -#1] &,
    Join[{{9820, 9822, 9821, 9819, 9818, 9821, 9822, 9820},
      Table[9823, {8}]}, ConstantArray[1, {4, 8}],
     {Table[9817, {8}],
      {9814, 9816, 9815, 9813, 9812, 9815, 9816, 9814}}], {2}]},
 ResourceFunction["CharacterArrayPlot"][chessBoard,
  ColorRules -> {x_ :> Association[
       1 -> Lighter[Yellow, .6],
       -1 -> Lighter[Orange, .6]][Sign[x]]},
  "CharacterStyleRules" -> {x_ :> {26, Black}},
  "CharacterRules" -> {1 -> "", -1 -> "", x_ :> FromCharacterCode[Abs[x]]},
  MeshStyle -> Directive[Gray, Thick]]]
Out[7]=

Or if you'd rather play a game of Xiangqi (象棋):

In[8]:=
With[{xiangqiBoard = {{36554, 39340, 35937, -22763,
     -23558, -22763, 35937, 39340, 36554},
    Join[ConstantArray[1, 3], ConstantArray[-1, 3], ConstantArray[1, 3]],
    {1, 30770, 1, -1, -1, -1, 1, 30770, 1},
    {21330, 1, 21330, 1, 21330, 1, 21330, 1, 21330},
    ConstantArray[0, 9], ConstantArray[0, 9],
    {20853, 1, 20853, 1, 20853, 1, 20853, 1, 20853},
    {1, 28846, 1, -1, -1, -1, 1, 28846, 1},
    Join[ConstantArray[1, 3], ConstantArray[-1, 3], ConstantArray[1, 3]],
    {20453, 20620, 30456, -20181,
     -24069, -20181, 30456, 20620, 20453}},
  black = First[ToCharacterCode[Last[#]]] & /@ {"General" -> "将",
     "Advisor" -> "士", "Elephant" -> "象", "Horse" -> "馬",
     "Rook" -> "車", "Cannon" -> "砲", "Pawn" -> "卒"},
  red = First[ToCharacterCode[Last[#]]] & /@ {"General" -> "帅",
     "Advisor" -> "仕", "Elephant" -> "相", "Horse" -> "傌",
     "Rook" -> "俥", "Cannon" -> "炮", "Pawn" -> "兵"}},
 ResourceFunction["CharacterArrayPlot"][xiangqiBoard,
  ColorRules -> {x_ :> Association[
       0 -> Lighter[Blue, .7],
       1 -> Lighter[Blend[{Brown, Green}, .35], .6],
       -1 -> Lighter[Brown, .6]][Sign[x]]},
  "CharacterStyleRules" -> Flatten[{
     {# -> {26, Darker@Red}, -# -> {26, Darker@Red}} & /@ red,
     {# -> {26, Black}, -# -> {26, Black}} & /@ black,
     {0 -> {15, LightBlue}}}],
  "CharacterRules" -> {1 -> "", 0 -> "~", x_ :> FromCharacterCode[Abs[x]]},
  MeshStyle -> Directive[Gray, Thick]]]
Out[8]=

Possible Issues (2) 

CharacterArrayPlot is not designed automatically scale text:

In[9]:=
ResourceFunction["CharacterArrayPlot"][{{1, 2}, {3, 4}},
   ColorRules -> {x_ :> Lighter[Hue[(x + 1)/6], .6]},
   "CharacterStyleRules" -> {x_ :> {12, Lighter[Hue[(6 - x)/6], .6]}},
   "CharacterRules" -> {1 -> "A", 2 -> "B", 3 -> "C", 4 -> "D"},
   MeshStyle -> Directive[Gray, Thick], ImageSize -> 30 #] & /@ Range[3]
Out[9]=

Using more than one character per cell can cause overflow:

In[10]:=
ResourceFunction["CharacterArrayPlot"][{{1, 2}, {3, 4}},
 ColorRules -> {x_ :> Lighter[Hue[(x + 1)/6], .6]},
 "CharacterStyleRules" -> {x_ :> {20, Lighter[Hue[(6 - x)/6], .6]}},
 "CharacterRules" -> {1 -> "A", 2 -> "BBBBBBBBB", 3 -> "C", 4 -> "D"},
 MeshStyle -> Directive[Gray, Thick], ImageSize -> 100]
Out[10]=

Neat Examples (2) 

Plot the initial condition of the "Moving Day" sliding block puzzle:

In[11]:=
ResourceFunction["CharacterArrayPlot"][{{1, 2, 3}, {4, 0, 5}},
 ColorRules -> MapIndexed[(#2[[1]] - 1) -> #1 &,
   Lighter /@ {White, Hue[0.08, 1, 0.97], Hue[0.61, 0.46, 0.89], Hue[
     0.23, 0.71, 0.79], Hue[0.81, 0.51, 0.85], Hue[0.53, 0.62, 0.89]}],
 "CharacterStyleRules" -> {x_ :> {10, Black}},
 "CharacterRules" -> {0 -> "\[Bullet]", x_ :> x},
 MeshStyle -> Directive[Gray, Thick], ImageSize -> 65]
Out[11]=

Plot possible moves as a branching Graph:

In[12]:=
With[{g0 = Graph[{{1, 2, 3}, {4, 0, 5}} -> # & /@ {
      {{1, 2, 3}, {4, 5, 0}},
      {{1, 2, 3}, {0, 4, 5}},
      {{1, 0, 3}, {4, 2, 5}}}, EdgeStyle -> Gray]}, Graph[g0,
  VertexSize -> 1, PerformanceGoal -> "Quality",
  GraphLayout -> "LayeredDigraphEmbedding",
  VertexShapeFunction -> (
    Inset[ResourceFunction["CharacterArrayPlot"][#2,
       ColorRules -> MapIndexed[(#2[[1]] - 1) -> #1 &,
         Lighter /@ {White, Hue[0.08, 1, 0.97], Hue[0.61, 0.46, 0.89],
            Hue[0.23, 0.71, 0.79], Hue[0.81, 0.51, 0.85], Hue[
           0.53, 0.62, 0.89]}],
       "CharacterStyleRules" -> {x_ :> {10, Black}},
       "CharacterRules" -> {0 -> "\[Bullet]", x_ :> x},
       MeshStyle -> Directive[Gray, Thick]
       ], #1, Center, #3] &)]]
Out[12]=

Publisher

Brad Klee

Version History

  • 1.0.0 – 17 June 2022

License Information