go-hep.org/x/hep@v0.38.1/hplot/tiledplot.go (about) 1 // Copyright ©2016 The go-hep Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package hplot 6 7 import ( 8 "gonum.org/v1/plot" 9 "gonum.org/v1/plot/vg" 10 "gonum.org/v1/plot/vg/draw" 11 ) 12 13 // TiledPlot is a regularly spaced set of plots, aranged as tiles. 14 type TiledPlot struct { 15 Plots []*Plot 16 Tiles draw.Tiles 17 Align bool // whether to align all tiles axes 18 } 19 20 // NewTiledPlot creates a new set of plots aranged as tiles. 21 // By default, NewTiledPlot will put a 1 vg.Length space between each plot. 22 func NewTiledPlot(tiles draw.Tiles) *TiledPlot { 23 const pad = 1 24 for _, v := range []*vg.Length{ 25 &tiles.PadTop, &tiles.PadBottom, &tiles.PadRight, &tiles.PadLeft, 26 &tiles.PadX, &tiles.PadY, 27 } { 28 if *v == 0 { 29 *v = pad 30 } 31 } 32 33 plot := &TiledPlot{ 34 Plots: make([]*Plot, tiles.Rows*tiles.Cols), 35 Tiles: tiles, 36 } 37 38 for i := range tiles.Rows { 39 for j := range tiles.Cols { 40 plot.Plots[i*tiles.Cols+j] = New() 41 } 42 } 43 44 return plot 45 } 46 47 // Plot returns the plot at the i-th column and j-th row in the set of 48 // tiles. 49 // (0,0) is at the top-left of the set of tiles. 50 func (tp *TiledPlot) Plot(i, j int) *Plot { 51 return tp.Plots[j*tp.Tiles.Cols+i] 52 } 53 54 // Draw draws the tiled plot to a draw.Canvas. 55 // 56 // Each non-nil plot.Plot in the aranged set of tiled plots is drawn 57 // inside its dedicated sub-canvas, using hplot.Plot.Draw. 58 func (tp *TiledPlot) Draw(c draw.Canvas) { 59 switch { 60 case tp.Align: 61 ps := make([][]*plot.Plot, tp.Tiles.Rows) 62 for row := range tp.Tiles.Rows { 63 ps[row] = make([]*plot.Plot, tp.Tiles.Cols) 64 for col := range ps[row] { 65 p := tp.Plots[row*tp.Tiles.Cols+col] 66 if p == nil { 67 continue 68 } 69 ps[row][col] = p.Plot 70 } 71 } 72 cs := plot.Align(ps, tp.Tiles, c) 73 for i := range tp.Tiles.Rows { 74 for j := range tp.Tiles.Cols { 75 p := ps[i][j] 76 if p == nil { 77 continue 78 } 79 p.Draw(cs[i][j]) 80 } 81 } 82 83 default: 84 for row := range tp.Tiles.Rows { 85 for col := range tp.Tiles.Cols { 86 sub := tp.Tiles.At(c, col, row) 87 i := row*tp.Tiles.Cols + col 88 p := tp.Plots[i] 89 if p == nil { 90 continue 91 } 92 p.Draw(sub) 93 } 94 } 95 } 96 } 97 98 // Save saves the plots to an image file. 99 // The file format is determined by the extension. 100 // 101 // Supported extensions are the same ones than hplot.Save. 102 // 103 // If w or h are <= 0, the value is chosen such that it follows the Golden Ratio. 104 // If w and h are <= 0, the values are chosen such that they follow the Golden Ratio 105 // (the width is defaulted to vgimg.DefaultWidth). 106 func (tp *TiledPlot) Save(w, h vg.Length, file string) error { 107 return Save(tp, w, h, file) 108 } 109 110 var ( 111 _ Drawer = (*TiledPlot)(nil) 112 )