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  )