Skip to content

Latest commit

 

History

History
316 lines (292 loc) · 15.6 KB

README.md

File metadata and controls

316 lines (292 loc) · 15.6 KB

AskiPlot

cout <<
  Plot(80,20)
    .DrawImage(Image("examples/logo.bmp").Invert(), TextGamma("askiplot"))
    .Serialize();
              a                                   s                             
           kiplo                        ta    skiplotas                         
          kiplot           aski        plot  as      kip  lota                  
         sk iplo           tas         kipl ot  ask   ip  lota             skip 
        lo  tas            kip          lotas  kipl   ot  ask              ipl  
       ot   ask           iplo            tas  kipl   ot  ask              ipl  
       ot  aski    plot   aski   pl    otaski  plo   tas kipl     otask   iplot 
  askiplo  task   iplot   ask   ip    lota sk  ipl   ota skip    lot as   kipl  
 ota ski plota    skipl   ota sk      iplo    task  ipl  ota    ski  plo  tas   
kip  lo    tas    kiplo   taskiplo    tas     kipl ota   ski   plot  askiplot   
 as kip    lot   a skip  lotaskipl    ota     skiplo     tas   kip   lot aski   
    pl    otas   k iplo  task  iplo   tas     kip       lota  skip   lo  task   
   ipl    ota   s   kip  lot   aski  plot    aski       plo   task   ip  lota   
   ski    plo  tas  kip lota   ski   plo     task       ipl   otas   ki  plo    
   ta     ski  p   lotaskipl   ota  skipl    ota        ski  plota  sk   ipl    
  ota    skip  lotaskip lota   skiplotaski   plo        taskiplotaski    plot   
  ask    iplo   taski   plo     task  ipl    ota        skipl  otask     iplo   
  tas                                                                           
  kip                                                                           

AskiPlot is a single-header library written in C++17 for creating plots with ASCII characters only. With AskiPlot you can plot grouped bars, histograms, boxes, lines and arrange text by specifying positions relative to the current console. Unless otherwise specified, the library will infere a canvas size that fits the console at run-time.

The library is designed for method chainining. All classes have a fluent interface. Static polymorhism is achieved through the use of the CRTP (Curiously Recurring Template Pattern).

Examples

Run make in the examples directory to compile all the examples.

Grouped bars

bar_grouper.cpp uses the class BarGrouper to group multiple sources in a single BarPlot.

BarPlot bp;
BarGrouper(bp, askiplot::kSymbolBrushes)
  .Add(vector<int>{80, 40}, "Data Source 1")
  .Add(vector<int>{20, 50}, "Data Source 2", Brush('x'))
  .Add(vector<int>{10, 20}, "Data Source 3")
  .SetGroupNames({"Group 1", "Group 2"})
  .ShowGroupNames(true)
  .Commit();
bp
  .DrawBarLabels(Offset(0, 1))
  .DrawLegend()
  .SetBrush("BorderTop", "/")
  .DrawBorders(Top + Right)
;
cout << bp.Serialize();

Produces the following:

////////////////////////////////////////////////////////////////////////////////
                                                            ___________________|
    80                                                      | @ Data Source 1 ||
 _________                                                  | x Data Source 2 ||
|@@@@@@@@@|                                                 | $ Data Source 3 ||
|@@@@@@@@@|                                                 |_________________||
|@@@@@@@@@|                                                                    |
|@@@@@@@@@|                                                                    |
|@@@@@@@@@|                                                                    |
|@@@@@@@@@|                                                                    |
|@@@@@@@@@|                                                50                  |
|@@@@@@@@@|                                             _________              |
|@@@@@@@@@|                                            |xxxxxxxxx|             |
|@@@@@@@@@|                                     40     |xxxxxxxxx|             |
|@@@@@@@@@|                                  _________ |xxxxxxxxx|             |
|@@@@@@@@@|                                 |@@@@@@@@@||xxxxxxxxx|             |
|@@@@@@@@@|                                 |@@@@@@@@@||xxxxxxxxx|             |
|@@@@@@@@@|                                 |@@@@@@@@@||xxxxxxxxx|             |
|@@@@@@@@@|    20                           |@@@@@@@@@||xxxxxxxxx|    20       |
|@@@@@@@@@| _________                       |@@@@@@@@@||xxxxxxxxx| _________   |
|@@@@@@@@@||xxxxxxxxx|    10                |@@@@@@@@@||xxxxxxxxx||$$$$$$$$$|  |
|@@@@@@@@@||xxxxxxxxx| _________            |@@@@@@@@@||xxxxxxxxx||$$$$$$$$$|  |
|@@@@@@@@@||xxxxxxxxx||$$$$$$$$$|           |@@@@@@@@@||xxxxxxxxx||$$$$$$$$$|  |
|@@@@@@@@@||xxxxxxxxx||$$$$$$$$$|           |@@@@@@@@@||xxxxxxxxx||$$$$$$$$$|  |
<___________ Group 1 ___________>           <___________ Group 2 ___________>  |

Histograms

gaussian.cpp uses the class HistPlot to plot a standard normal distribution.

HistPlot hp;
hp
  .DrawBorders(All)
  .SetTitle("Gaussian distribution")
  .DrawTitle()
  .SetBrush("Area", "@")
  .SetBrush("BorderTop", " ")
  .PlotHistogram(gsamples, "Normal (0,1)")
  .DrawText("Number of samples: " + to_string(N), NorthWest + Offset(2, -2))
  .DrawLegend()
;
cout << hp.Serialize();

Produces the following:

______________________________Gaussian distribution_____________________________
|                                                            __________________|
| Number of samples: 10000                                   | @ Normal (0,1) ||
|                                                            |________________||
|                                                                              |
|                                      @                                       |
|                                      @  @                                    |
|                                  @  @@@@@                                    |
|                                  @ @@@@@@@ @                                 |
|                                 @@@@@@@@@@@@                                 |
|                                 @@@@@@@@@@@@                                 |
|                               @ @@@@@@@@@@@@@@                               |
|                              @@@@@@@@@@@@@@@@@                               |
|                             @@@@@@@@@@@@@@@@@@@@                             |
|                            @@@@@@@@@@@@@@@@@@@@@@                            |
|                           @@@@@@@@@@@@@@@@@@@@@@@@@@                         |
|                          @@@@@@@@@@@@@@@@@@@@@@@@@@@                         |
|                          @@@@@@@@@@@@@@@@@@@@@@@@@@@@                        |
|                       @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                       |
|                     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                     |
|                    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                     |
|                  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                   |
                @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @              

Images

turing.cpp shows that plotting BMP images is as simple as:

cout << Plot{}.DrawImage(Image("turing.bmp")).Serialize();
@@@@@@@@@@@@@@@@@@@@@@@@#######0000oo............... ...o0##@##########00000000000
@@@@@@@@@@@@@@@@@@@@@@@@####0o..oo........       .       ..0#########0000000000000
@@@@@@@@@@@@@@@@@@@@@@@#@#0.  ...     ..                    o#########000000000000
@@@@@@@@@@@@@@@@@@@@@@@##o          .....................   .0#######0000000000000
@@@@@@@@@@@@@@@@@@@@@@@#0   .  ..oo0000000000000000o....     .0######0000000000000
@@@@@@@@@@@@@@@@@@@@@@@#.  ..o00###@#@########000000o.        .0#####0000000000000
@@@@@@@@@@@@@@@@@@@@@@@o   o0##@@@@#############00000..        .0###00000000000000
@@@@@@@@@@@@@@@@@@@@@@#.  o#@@@@@@@@###########00000o..         o###0000000000000o
@@@@@@@@@@@@@@@@@@@@@@@o.0##@@@@##@@@######000000000o...        o###0000000000000o
@@@@@@@@@@@@@@@@@@@@@@#o0###@@@@@@@@####00000000000ooo...       o###0000000000000o
@@@@@@@@@@@@@@@@@@@@@@@#00000######000oo..oooooo0000oo.......   0###0000000000000o
@@@@@@@@@@@@@@@@@@@@####o....oo0000o..   .......ooo0ooooo.oo....0###0000000000000o
@@@@@@@@@@@@@@@@@@@@@@@#0......0##0o.............oooooooooo00oo.o0##0000000000000o
@@@@@@@@@@@@@@@@@@@######000000##00000000oooooooo0oooooooo0oo00ooo##0000000000000o
@@@@@@@@@@@@@@@@@@@@@@#@#0#######000000000000000000oooooooo.oo0oo0##0000000000000o
@@@@@@@@@@@@@@@@@@@####@########000000#######0000oooooooo0o0oooo0###0000000000000o
@@@@@@@@@@@@@@@@@######@####0ooo..ooo0000###00000ooooooo0o00ooo0####0000000000000o
@@@@@@@@@@@@@@@@@@###@@@#000000ooooo0000000000ooooooooooo000o0#####00000000000000o
@@@@@@#@@@@@@@@@@@#@##@@@#00000000000000000oooooooooooooooo0#######0000000000000oo
@@@@@@@@@@@@@@@@@@@@@#####00oo0ooooooo..oooooooooooooooo..0#######00000000000000oo
@@@@@@@@@@@@@@@@@@@@@@@@@#00000ooooooooooooooooooooooo...o0#######00000000000000oo
@@@@@@@@@@@@@@@@@@@@@@@@@@#0##00ooooo0000ooooooooooo....o..o#####000000000000000oo
@@@@@@@@@@@@@@@@@@@@@@@@@@@000000000000ooo....oo.......ooo...0###0000000000000000o
#@@@@@@@@@@@@@@@@@@@@@@@@@@#000000ooooo........... ...oooo....o00000000000000000oo
@@@@@@@@@@@@@@@@@@@@@@@@@@@@##0oo.....   ..      ...ooo0o.........ooooo000000000oo
@@@@@@@@@@@@@@@@@@@@@@@@##00000o0o0oo..     .....ooo000o.... ............ooooooooo
@@@@@@@@@@@@@@@@@###000ooooo0oo.00o000oo......ooo000000... .......................
@@@@@@@@@@@@#0000oooooooooooooo.o##0oo00oooooo00000000..............  ............
@@@@@@###00oooooooo.ooooo0ooooo..0#@##000000#0##0000o........ .... ... ...........
@@@@#0o.oooooooo....oooooooooo...o#@@@#...0####00000o................. ...........
@@@#oo..ooooo........oooooooooo.o##@@#..   0000###0o................  ............
@@#oo...oooo......oooooooooooo..#@@@0.. ....0##0o.................  ........... ..
@#0oo....oo.....oooooooooooooo. oooo.   .0#0000o0o.....o..........................
0o.oo....oo....ooooooooooooooo...o0...  .0000#@@0o..........o................. . .
ooo.....oo......ooooooooooooo..o00o      .00##@0o................... .......   ...
..ooo...oo....o.ooooooooooooo...00o       o0#@0oo.................. .......    ...
o...o..oooo..oo.ooooooooooooo.. o0.        0##......oo............ ........   ...

Text and lines

textlines.cpp demonstrates how to draw horizontal or vertical text and lines. At every cardinal point, text is adjusted so to fit the console's boundaries.

Plot p;
p
 .SetBrush("LineVertical", DefaultBrushLineVertical) // Optional
 .DrawLineVerticalAtCol(13)
 .DrawLineVerticalAtCol(15)
 .SetBrush("LineVertical", "!")
 .DrawLineVerticalAtCol(0.5)
 .SetBrush("LineHorizontal", ".")
 .DrawLineHorizontalAtRow(p.GetHeight() - 2)
 .DrawLineHorizontalAtRow(1)
 .DrawText("North", North)
 .DrawText("South", South)
 .DrawText("East", East)
 .DrawText("West", West)
 .DrawText("NorthEast", NorthEast)
 .DrawText("NorthWest", NorthWest)
 .DrawText("SouthEast", SouthEast)
 .DrawText("SouthWest", SouthWest)
 .DrawText("Center", Center)
 .DrawTextCentered("Centered text at South + Offset(0,2)", South + Offset(0,2))
 .DrawTextCentered("Centered text at South", South)
 .SetBrush("LineHorizontal", ">")
 .DrawLineHorizontalAtRow(0.66)
 .SetBrush("LineHorizontal", "<")
 .DrawLineHorizontalAtRow(0.33)
 .DrawTextVerticalCentered("Vertical text", East - Offset(10,0))
 .DrawText("{3,3}", {3,3})
;
cout << p.Serialize();

Produces the following:

NorthWest    | |                        North                          NorthEast
................................................................................
             | |                        !                                       
             | |                        !                                       
             | |                        !                                       
             | |                        !                            V          
             | |                        !                            e          
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>r>>>>>>>>>>
             | |                        !                            t          
             | |                        !                            i          
             | |                        !                            c          
West         | |                        Center                       a      East
             | |                        !                            l          
             | |                        !                                       
             | |                        !                            t          
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<e<<<<<<<<<<
             | |                        !                            x          
             | |                        !                            t          
             | |                        !                                       
   {3,3}     | |                        !                                       
             | |      Centered text at South + Offset(0,2)                      
................................................................................
SouthWest    | |             Centered text at South                    SouthEast

Fusion

fusion.cpp demonstrates how to fuse (compose) any plot together.

auto box1 = Plot(10,5).Fill(".").DrawTextCentered("BOX1", Center);
auto box2 = Plot(box1).DrawTextCentered("BOX2", Center);

Plot p(60,15);
p
  .Fuse(box1, NorthWest)
  .Fuse(box1, SouthEast)
  .Fuse(box2, NorthEast)
  .Fuse(box2, SouthWest)
  .DrawLineHorizontalAtRow(0.5)
  .DrawLineVerticalAtCol(0.5)
;
cout << p.Serialize();

Produces the following:

..........                    |                   ..........
..........                    |                   ..........
...BOX1...                    |                   ...BOX2...
..........                    |                   ..........
..........                    |                   ..........
                              |
                              |
------------------------------|-----------------------------
                              |
                              |
..........                    |                   ..........
..........                    |                   ..........
...BOX2...                    |                   ...BOX1...
..........                    |                   ..........
..........                    |                   ..........

Grid

grid.cpp shows how to merge multiple plots into a simple grid.

int width = 10, height = 5;
GridPlot gp(2, 3, 3 * width, 2 * height); // Rows, Columns, Width, Height
Plot base = Plot(width, height).Fill().DrawBorders(All - Bottom);

Plot sp1 = Plot(base).SetMainBrush("1").Redraw();
Plot sp2 = Plot(base).SetMainBrush("2").Redraw();
Plot sp3 = Plot(base).SetMainBrush("3").Redraw();

gp.SetInRowMajor()(sp1)(sp2)(sp3)(sp3)(sp2)(sp1).Set();
gp.Get<Plot>(1,2).DrawTextCentered("--", Center);

cout << gp.Serialize();

Produces the following:

______________________________
|11111111||22222222||33333333|
|111--111||22222222||33333333|
|11111111||22222222||33333333|
|11111111||22222222||33333333|
______________________________
|33333333||22222222||11111111|
|33333333||22222222||111--111|
|33333333||22222222||11111111|
|33333333||22222222||11111111|

Build on AskiPlot

  • askibench: plotting benchmark results with grouped bars.