go-hep.org/x/hep@v0.38.1/hplot/h1d_example_test.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_test
     6  
     7  import (
     8  	"image/color"
     9  	"log"
    10  	"math/rand/v2"
    11  
    12  	"go-hep.org/x/hep/hbook"
    13  	"go-hep.org/x/hep/hplot"
    14  	"gonum.org/v1/gonum/stat/distuv"
    15  	"gonum.org/v1/plot"
    16  	"gonum.org/v1/plot/plotutil"
    17  	"gonum.org/v1/plot/vg"
    18  	"gonum.org/v1/plot/vg/draw"
    19  )
    20  
    21  // An example of making a 1D-histogram.
    22  func ExampleH1D() {
    23  	const npoints = 10000
    24  
    25  	// Create a normal distribution.
    26  	dist := distuv.Normal{
    27  		Mu:    0,
    28  		Sigma: 1,
    29  		Src:   rand.New(rand.NewPCG(0, 0)),
    30  	}
    31  
    32  	// Draw some random values from the standard
    33  	// normal distribution.
    34  	hist := hbook.NewH1D(20, -4, +4)
    35  	for range npoints {
    36  		v := dist.Rand()
    37  		hist.Fill(v, 1)
    38  	}
    39  
    40  	// normalize histogram
    41  	area := 0.0
    42  	for _, bin := range hist.Binning.Bins {
    43  		area += bin.SumW() * bin.XWidth()
    44  	}
    45  	hist.Scale(1 / area)
    46  
    47  	// Make a plot and set its title.
    48  	p := hplot.New()
    49  	p.Title.Text = "Histogram"
    50  	p.X.Label.Text = "X"
    51  	p.Y.Label.Text = "Y"
    52  
    53  	// Create a histogram of our values drawn
    54  	// from the standard normal.
    55  	h := hplot.NewH1D(hist)
    56  	h.Infos.Style = hplot.HInfoSummary
    57  	p.Add(h)
    58  
    59  	// The normal distribution function
    60  	norm := hplot.NewFunction(dist.Prob)
    61  	norm.Color = color.RGBA{R: 255, A: 255}
    62  	norm.Width = vg.Points(2)
    63  	p.Add(norm)
    64  
    65  	// draw a grid
    66  	p.Add(hplot.NewGrid())
    67  
    68  	// Save the plot to a PNG file.
    69  	if err := p.Save(6*vg.Inch, -1, "testdata/h1d_plot.png"); err != nil {
    70  		log.Fatalf("error saving plot: %v\n", err)
    71  	}
    72  }
    73  
    74  // An example of making a 1D-histogram and saving to a PDF
    75  func ExampleH1D_toPDF() {
    76  	const npoints = 10000
    77  
    78  	// Create a normal distribution.
    79  	dist := distuv.Normal{
    80  		Mu:    0,
    81  		Sigma: 1,
    82  		Src:   rand.New(rand.NewPCG(0, 0)),
    83  	}
    84  
    85  	// Draw some random values from the standard
    86  	// normal distribution.
    87  	hist := hbook.NewH1D(20, -4, +4)
    88  	for range npoints {
    89  		v := dist.Rand()
    90  		hist.Fill(v, 1)
    91  	}
    92  
    93  	// normalize histogram
    94  	area := 0.0
    95  	for _, bin := range hist.Binning.Bins {
    96  		area += bin.SumW() * bin.XWidth()
    97  	}
    98  	hist.Scale(1 / area)
    99  
   100  	// Make a plot and set its title.
   101  	p := hplot.New()
   102  	p.Title.Text = "Histogram"
   103  	p.X.Label.Text = "X"
   104  	p.Y.Label.Text = "Y"
   105  
   106  	// Create a histogram of our values drawn
   107  	// from the standard normal.
   108  	h := hplot.NewH1D(hist)
   109  	h.Infos.Style = hplot.HInfoSummary
   110  	p.Add(h)
   111  
   112  	// The normal distribution function
   113  	norm := hplot.NewFunction(dist.Prob)
   114  	norm.Color = color.RGBA{R: 255, A: 255}
   115  	norm.Width = vg.Points(2)
   116  	p.Add(norm)
   117  
   118  	// draw a grid
   119  	p.Add(hplot.NewGrid())
   120  
   121  	// Save the plot to a PNG file.
   122  	if err := p.Save(6*vg.Inch, -1, "testdata/h1d_plot.pdf"); err != nil {
   123  		log.Fatalf("error saving plot: %v\n", err)
   124  	}
   125  }
   126  
   127  func ExampleH1D_logScaleY() {
   128  	p := hplot.New()
   129  	p.Title.Text = "Histogram in log-y"
   130  	p.Y.Scale = plot.LogScale{}
   131  	p.Y.Tick.Marker = plot.LogTicks{}
   132  	p.Y.Label.Text = "Y"
   133  	p.X.Label.Text = "X"
   134  
   135  	h1 := hbook.NewH1D(10, -5, +5)
   136  	for _, v := range []float64{
   137  		-2, -2,
   138  		-1,
   139  		+3, +3, +3, +3,
   140  		+1, +1, +1, +1, +1, +1, +1, +1, +1, +1,
   141  		+1, +1, +1, +1, +1, +1, +1, +1, +1, +1,
   142  	} {
   143  		h1.Fill(v, 1)
   144  	}
   145  	p1 := hplot.NewH1D(h1)
   146  	p1.LogY = true
   147  	p1.FillColor = color.RGBA{255, 0, 0, 255}
   148  
   149  	h2 := hbook.NewH1D(10, -5, +5)
   150  	for _, v := range []float64{
   151  		-3, -3, -3,
   152  		+2, +2, +2, +2, +2,
   153  	} {
   154  		h2.Fill(v, 1)
   155  	}
   156  	p2 := hplot.NewH1D(h2,
   157  		hplot.WithYErrBars(true),
   158  		hplot.WithLogY(true),
   159  		hplot.WithGlyphStyle(draw.GlyphStyle{
   160  			Color:  color.Black,
   161  			Radius: 2,
   162  			Shape:  draw.CircleGlyph{},
   163  		}),
   164  	)
   165  	p2.FillColor = color.RGBA{0, 0, 255, 255}
   166  
   167  	p.Add(p1, p2, hplot.NewGrid())
   168  
   169  	err := p.Save(6*vg.Inch, -1, "testdata/h1d_logy.png")
   170  	if err != nil {
   171  		log.Fatal(err)
   172  	}
   173  }
   174  
   175  // An example of making a 1D-histogram with y-error bars.
   176  func ExampleH1D_withYErrBars() {
   177  	const npoints = 100
   178  
   179  	// Create a normal distribution.
   180  	dist := distuv.Normal{
   181  		Mu:    0,
   182  		Sigma: 1,
   183  		Src:   rand.New(rand.NewPCG(0, 0)),
   184  	}
   185  
   186  	// Draw some random values from the standard
   187  	// normal distribution.
   188  	hist := hbook.NewH1D(20, -4, +4)
   189  	for range npoints {
   190  		v := dist.Rand()
   191  		hist.Fill(v, 1)
   192  	}
   193  
   194  	// normalize histogram
   195  	area := 0.0
   196  	for _, bin := range hist.Binning.Bins {
   197  		area += bin.SumW() * bin.XWidth()
   198  	}
   199  	hist.Scale(1 / area)
   200  
   201  	// Make a plot and set its title.
   202  	p := hplot.New()
   203  	p.Title.Text = "Histogram"
   204  	p.X.Label.Text = "X"
   205  	p.Y.Label.Text = "Y"
   206  
   207  	// Create a histogram of our values drawn
   208  	// from the standard normal.
   209  	h := hplot.NewH1D(hist,
   210  		hplot.WithHInfo(hplot.HInfoSummary),
   211  		hplot.WithYErrBars(true),
   212  	)
   213  	h.YErrs.LineStyle.Color = color.RGBA{R: 255, A: 255}
   214  	p.Add(h)
   215  
   216  	// The normal distribution function
   217  	norm := hplot.NewFunction(dist.Prob)
   218  	norm.Color = color.RGBA{R: 255, A: 255}
   219  	norm.Width = vg.Points(2)
   220  	p.Add(norm)
   221  
   222  	// draw a grid
   223  	p.Add(hplot.NewGrid())
   224  
   225  	// Save the plot to a PNG file.
   226  	if err := p.Save(6*vg.Inch, -1, "testdata/h1d_yerrs.png"); err != nil {
   227  		log.Fatalf("error saving plot: %v\n", err)
   228  	}
   229  }
   230  
   231  // An example of making a 1D-histogram with y-error bars
   232  // and the associated band.
   233  func ExampleH1D_withYErrBars_withBand() {
   234  	const npoints = 100
   235  
   236  	// Create a normal distribution.
   237  	dist := distuv.Normal{
   238  		Mu:    0,
   239  		Sigma: 1,
   240  		Src:   rand.New(rand.NewPCG(0, 0)),
   241  	}
   242  
   243  	// Draw some random values from the standard
   244  	// normal distribution.
   245  	hist := hbook.NewH1D(20, -4, +4)
   246  	for range npoints {
   247  		v := dist.Rand()
   248  		hist.Fill(v, 1)
   249  	}
   250  
   251  	// normalize histogram
   252  	area := 0.0
   253  	for _, bin := range hist.Binning.Bins {
   254  		area += bin.SumW() * bin.XWidth()
   255  	}
   256  	hist.Scale(1 / area)
   257  
   258  	// Make a plot and set its title.
   259  	p := hplot.New()
   260  	p.Title.Text = "Histogram"
   261  	p.X.Label.Text = "X"
   262  	p.Y.Label.Text = "Y"
   263  
   264  	// Create a histogram of our values drawn
   265  	// from the standard normal.
   266  	h := hplot.NewH1D(hist,
   267  		hplot.WithHInfo(hplot.HInfoSummary),
   268  		hplot.WithYErrBars(true),
   269  		hplot.WithBand(true),
   270  	)
   271  	h.YErrs.LineStyle.Color = color.RGBA{R: 255, A: 255}
   272  	p.Add(h)
   273  
   274  	// The normal distribution function
   275  	norm := hplot.NewFunction(dist.Prob)
   276  	norm.Color = color.RGBA{R: 255, A: 255}
   277  	norm.Width = vg.Points(2)
   278  	p.Add(norm)
   279  
   280  	// draw a grid
   281  	p.Add(hplot.NewGrid())
   282  
   283  	// Save the plot to a PNG file.
   284  	if err := p.Save(6*vg.Inch, -1, "testdata/h1d_yerrs_band.png"); err != nil {
   285  		log.Fatalf("error saving plot: %v\n", err)
   286  	}
   287  }
   288  
   289  // An example of making a 1D-histogram with y-error bars
   290  // and no histogram rectangle.
   291  func ExampleH1D_withYErrBarsAndData() {
   292  	const npoints = 100
   293  
   294  	// Create a normal distribution.
   295  	dist := distuv.Normal{
   296  		Mu:    0,
   297  		Sigma: 1,
   298  		Src:   rand.New(rand.NewPCG(0, 0)),
   299  	}
   300  
   301  	// Draw some random values from the standard
   302  	// normal distribution.
   303  	hist := hbook.NewH1D(20, -4, +4)
   304  	for range npoints {
   305  		v := dist.Rand()
   306  		hist.Fill(v, 1)
   307  	}
   308  
   309  	// normalize histogram
   310  	area := 0.0
   311  	for _, bin := range hist.Binning.Bins {
   312  		area += bin.SumW() * bin.XWidth()
   313  	}
   314  	hist.Scale(1 / area)
   315  
   316  	// Make a plot and set its title.
   317  	p := hplot.New()
   318  	p.Title.Text = "Histogram"
   319  	p.X.Label.Text = "X"
   320  	p.Y.Label.Text = "Y"
   321  
   322  	p.Legend.Top = true
   323  	p.Legend.Left = true
   324  
   325  	// Create a histogram of our values drawn
   326  	// from the standard normal.
   327  	h := hplot.NewH1D(hist,
   328  		hplot.WithHInfo(hplot.HInfoSummary),
   329  		hplot.WithYErrBars(true),
   330  		hplot.WithGlyphStyle(draw.GlyphStyle{
   331  			Shape:  draw.CrossGlyph{},
   332  			Color:  color.Black,
   333  			Radius: vg.Points(2),
   334  		}),
   335  	)
   336  	h.GlyphStyle.Shape = draw.CircleGlyph{}
   337  	h.YErrs.LineStyle.Color = color.Black
   338  	h.LineStyle.Width = 0 // disable histogram lines
   339  	p.Add(h)
   340  	p.Legend.Add("data", h)
   341  
   342  	// The normal distribution function
   343  	norm := hplot.NewFunction(dist.Prob)
   344  	norm.Color = color.RGBA{R: 255, A: 255}
   345  	norm.Width = vg.Points(2)
   346  	p.Add(norm)
   347  	p.Legend.Add("model", norm)
   348  
   349  	// draw a grid
   350  	p.Add(hplot.NewGrid())
   351  
   352  	// Save the plot to a PNG file.
   353  	if err := p.Save(6*vg.Inch, -1, "testdata/h1d_glyphs.png"); err != nil {
   354  		log.Fatalf("error saving plot: %v\n", err)
   355  	}
   356  }
   357  
   358  // An example of making a 1D-histogram.
   359  func ExampleH1D_withPlotBorders() {
   360  	const npoints = 10000
   361  
   362  	// Create a normal distribution.
   363  	dist := distuv.Normal{
   364  		Mu:    0,
   365  		Sigma: 1,
   366  		Src:   rand.New(rand.NewPCG(0, 0)),
   367  	}
   368  
   369  	// Draw some random values from the standard
   370  	// normal distribution.
   371  	hist := hbook.NewH1D(20, -4, +4)
   372  	for range npoints {
   373  		v := dist.Rand()
   374  		hist.Fill(v, 1)
   375  	}
   376  
   377  	// normalize histogram
   378  	area := 0.0
   379  	for _, bin := range hist.Binning.Bins {
   380  		area += bin.SumW() * bin.XWidth()
   381  	}
   382  	hist.Scale(1 / area)
   383  
   384  	// Make a plot and set its title.
   385  	p := hplot.New()
   386  	p.Title.Text = "Histogram"
   387  	p.X.Label.Text = "X"
   388  	p.Y.Label.Text = "Y"
   389  
   390  	// Create a histogram of our values drawn
   391  	// from the standard normal.
   392  	h := hplot.NewH1D(hist)
   393  	h.Infos.Style = hplot.HInfoSummary
   394  	p.Add(h)
   395  
   396  	// The normal distribution function
   397  	norm := hplot.NewFunction(dist.Prob)
   398  	norm.Color = color.RGBA{R: 255, A: 255}
   399  	norm.Width = vg.Points(2)
   400  	p.Add(norm)
   401  
   402  	// draw a grid
   403  	p.Add(hplot.NewGrid())
   404  
   405  	fig := hplot.Figure(p,
   406  		hplot.WithDPI(96),
   407  		hplot.WithBorder(hplot.Border{
   408  			Right:  25,
   409  			Left:   20,
   410  			Top:    25,
   411  			Bottom: 20,
   412  		}),
   413  	)
   414  
   415  	// Save the plot to a PNG file.
   416  	if err := hplot.Save(fig, 6*vg.Inch, -1, "testdata/h1d_borders.png"); err != nil {
   417  		log.Fatalf("error saving plot: %v\n", err)
   418  	}
   419  }
   420  
   421  // An example showing legend with different style
   422  func ExampleH1D_legendStyle() {
   423  
   424  	const npoints = 500
   425  
   426  	// Create a few normal distributions.
   427  	var hists [5]*hbook.H1D
   428  	for id := range [5]int{0, 1, 2, 3, 4} {
   429  		mu := -2. + float64(id)*2
   430  		sigma := 0.3
   431  
   432  		dist := distuv.Normal{
   433  			Mu:    mu,
   434  			Sigma: sigma,
   435  			Src:   rand.New(rand.NewPCG(uint64(id), uint64(id))),
   436  		}
   437  
   438  		// Draw some random values from the standard
   439  		// normal distribution.
   440  		hists[id] = hbook.NewH1D(15, mu-4*sigma, mu+4*sigma)
   441  		for range npoints {
   442  			v := dist.Rand()
   443  			hists[id].Fill(v, 1)
   444  		}
   445  	}
   446  
   447  	// Make a plot and set its title.
   448  	p := hplot.New()
   449  	p.Title.Text = "Histograms"
   450  	p.X.Label.Text = "X"
   451  	p.Y.Label.Text = "Y"
   452  	p.X.Min = -3
   453  	p.X.Max = 15
   454  
   455  	// Legend style tunning
   456  	p.Legend.Top = true
   457  	p.Legend.ThumbnailWidth = 0.5 * vg.Inch
   458  	p.Legend.TextStyle.Font.Size = 11
   459  	p.Legend.Padding = 0.1 * vg.Inch
   460  
   461  	// Histogram with line and markers
   462  	hmarker := hplot.NewH1D(hists[0],
   463  		hplot.WithYErrBars(true),
   464  		hplot.WithGlyphStyle(draw.GlyphStyle{
   465  			Color:  color.Black,
   466  			Radius: 2,
   467  			Shape:  draw.CircleGlyph{},
   468  		}),
   469  	)
   470  	hmarker.LineStyle.Color = color.NRGBA{R: 200, G: 30, A: 255}
   471  	hmarker.LineStyle.Width = 1
   472  	hmarker.LineStyle.Dashes = plotutil.Dashes(2)
   473  	p.Add(hmarker)
   474  	p.Legend.Add("marker & line", hmarker)
   475  
   476  	// Histogram with fill and line
   477  	hfill := hplot.NewH1D(hists[1])
   478  	hfill.FillColor = color.NRGBA{R: 200, A: 130}
   479  	hfill.LineStyle.Color = color.NRGBA{R: 200, G: 30, A: 255}
   480  	hfill.LineStyle.Width = 1.3
   481  	p.Add(hfill)
   482  	p.Legend.Add("fill & line", hfill)
   483  
   484  	// Histogram with error band
   485  	hband := hplot.NewH1D(hists[2], hplot.WithBand(true))
   486  	hband.LineStyle.Width = 1.0
   487  	p.Add(hband)
   488  	p.Legend.Add("line & band", hband)
   489  
   490  	// Histogram with fill, line and band
   491  	hfillband := hplot.NewH1D(hists[3],
   492  		hplot.WithBand(true),
   493  	)
   494  	hfillband.FillColor = color.NRGBA{B: 200, A: 180}
   495  	hfillband.LineStyle.Color = color.NRGBA{B: 200, G: 30, A: 255}
   496  	hfillband.LineStyle.Width = 1.3
   497  	hfillband.Band.FillColor = color.NRGBA{R: 180, G: 180, B: 180, A: 180}
   498  	p.Add(hfillband)
   499  	p.Legend.Add("fill, line & band", hfillband)
   500  
   501  	// Histogram with fill, line, markers and band
   502  	hall := hplot.NewH1D(hists[4],
   503  		hplot.WithBand(true),
   504  		hplot.WithYErrBars(true),
   505  		hplot.WithGlyphStyle(draw.GlyphStyle{
   506  			Color:  color.Black,
   507  			Radius: 2,
   508  			Shape:  draw.CircleGlyph{},
   509  		}),
   510  	)
   511  	hall.FillColor = color.NRGBA{G: 160, A: 180}
   512  	hall.LineStyle.Color = color.NRGBA{G: 250, B: 60, R: 20, A: 255}
   513  	hall.LineStyle.Width = 1.3
   514  	p.Add(hall)
   515  	p.Legend.Add("fill, marker, line & band", hall)
   516  
   517  	// Create a figure
   518  	fig := hplot.Figure(p, hplot.WithDPI(192.))
   519  	fig.Border.Right = 15
   520  	fig.Border.Left = 10
   521  	fig.Border.Top = 10
   522  	fig.Border.Bottom = 10
   523  
   524  	// Save the figure to a PNG file.
   525  	if err := hplot.Save(fig, 6*vg.Inch, -1, "testdata/h1d_legend.png"); err != nil {
   526  		log.Fatalf("error saving plot: %v\n", err)
   527  	}
   528  }