...

Source file src/gonum.org/v1/plot/plotter/scatterColor_example_test.go

Documentation: gonum.org/v1/plot/plotter

     1  // Copyright ©2015 The Gonum 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 plotter_test
     6  
     7  import (
     8  	"fmt"
     9  	"log"
    10  	"math"
    11  	"os"
    12  
    13  	"golang.org/x/exp/rand"
    14  
    15  	"gonum.org/v1/plot"
    16  	"gonum.org/v1/plot/palette/moreland"
    17  	"gonum.org/v1/plot/plotter"
    18  	"gonum.org/v1/plot/vg"
    19  	"gonum.org/v1/plot/vg/draw"
    20  	"gonum.org/v1/plot/vg/vgimg"
    21  )
    22  
    23  // ExampleScatter_color draws a colored scatter plot.
    24  // Each point is plotted with a different color depending on
    25  // external criteria.
    26  func ExampleScatter_color() {
    27  	rnd := rand.New(rand.NewSource(1))
    28  
    29  	// randomTriples returns some random but correlated x, y, z triples
    30  	randomTriples := func(n int) plotter.XYZs {
    31  		data := make(plotter.XYZs, n)
    32  		for i := range data {
    33  			if i == 0 {
    34  				data[i].X = rnd.Float64()
    35  			} else {
    36  				data[i].X = data[i-1].X + 2*rnd.Float64()
    37  			}
    38  			data[i].Y = data[i].X + 10*rnd.Float64()
    39  			data[i].Z = data[i].X
    40  		}
    41  		return data
    42  	}
    43  
    44  	n := 15
    45  	scatterData := randomTriples(n)
    46  
    47  	// Calculate the range of Z values.
    48  	minZ, maxZ := math.Inf(1), math.Inf(-1)
    49  	for _, xyz := range scatterData {
    50  		if xyz.Z > maxZ {
    51  			maxZ = xyz.Z
    52  		}
    53  		if xyz.Z < minZ {
    54  			minZ = xyz.Z
    55  		}
    56  	}
    57  
    58  	colors := moreland.Kindlmann() // Initialize a color map.
    59  	colors.SetMax(maxZ)
    60  	colors.SetMin(minZ)
    61  
    62  	p := plot.New()
    63  	p.Title.Text = "Colored Points Example"
    64  	p.X.Label.Text = "X"
    65  	p.Y.Label.Text = "Y"
    66  	p.Add(plotter.NewGrid())
    67  
    68  	sc, err := plotter.NewScatter(scatterData)
    69  	if err != nil {
    70  		log.Panic(err)
    71  	}
    72  
    73  	// Specify style and color for individual points.
    74  	sc.GlyphStyleFunc = func(i int) draw.GlyphStyle {
    75  		_, _, z := scatterData.XYZ(i)
    76  		d := (z - minZ) / (maxZ - minZ)
    77  		rng := maxZ - minZ
    78  		k := d*rng + minZ
    79  		c, err := colors.At(k)
    80  		if err != nil {
    81  			log.Panic(err)
    82  		}
    83  		return draw.GlyphStyle{Color: c, Radius: vg.Points(3), Shape: draw.CircleGlyph{}}
    84  	}
    85  	p.Add(sc)
    86  
    87  	//Create a legend
    88  	thumbs := plotter.PaletteThumbnailers(colors.Palette(n))
    89  	for i := len(thumbs) - 1; i >= 0; i-- {
    90  		t := thumbs[i]
    91  		if i != 0 && i != len(thumbs)-1 {
    92  			p.Legend.Add("", t)
    93  			continue
    94  		}
    95  		var val int
    96  		switch i {
    97  		case 0:
    98  			val = int(minZ)
    99  		case len(thumbs) - 1:
   100  			val = int(maxZ)
   101  		}
   102  		p.Legend.Add(fmt.Sprintf("%d", val), t)
   103  	}
   104  
   105  	// This is the width of the legend, experimentally determined.
   106  	const legendWidth = vg.Centimeter
   107  
   108  	// Slide the legend over so it doesn't overlap the ScatterPlot.
   109  	p.Legend.XOffs = legendWidth
   110  
   111  	img := vgimg.New(300, 230)
   112  	dc := draw.New(img)
   113  	dc = draw.Crop(dc, 0, -legendWidth, 0, 0) // Make space for the legend.
   114  	p.Draw(dc)
   115  
   116  	w, err := os.Create("testdata/scatterColor.png")
   117  	if err != nil {
   118  		log.Panic(err)
   119  	}
   120  	defer w.Close()
   121  	png := vgimg.PngCanvas{Canvas: img}
   122  	if _, err = png.WriteTo(w); err != nil {
   123  		log.Panic(err)
   124  	}
   125  	if err = w.Close(); err != nil {
   126  		log.Panic(err)
   127  	}
   128  }
   129  

View as plain text