// Copyright ©2016 The Gonum Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package plotter_test import ( "image/color" "log" "math" "gonum.org/v1/plot" "gonum.org/v1/plot/palette/moreland" "gonum.org/v1/plot/plotter" "gonum.org/v1/plot/vg" ) // ExamplePolygon_holes draws a polygon with holes, showing how // the different built-in vg backends render polygons with holes. // The output of this example is at // https://github.com/gonum/plot/blob/master/plotter/testdata/polygon_holes_golden.png, // https://github.com/gonum/plot/blob/master/plotter/testdata/polygon_holes_golden.svg, // https://github.com/gonum/plot/blob/master/plotter/testdata/polygon_holes_golden.pdf, and // https://github.com/gonum/plot/blob/master/plotter/testdata/polygon_holes_golden.eps. func ExamplePolygon_holes() { // Create an outer ring. outer1 := plotter.XYs{{X: 0, Y: 0}, {X: 4, Y: 0}, {X: 4, Y: 4}, {X: 0, Y: 4}} // Create an inner ring with the same // winding order as the outer ring. inner1 := plotter.XYs{{X: 0.5, Y: 0.5}, {X: 1.5, Y: 0.5}, {X: 1.5, Y: 1.5}, {X: 0.5, Y: 1.5}} // Create an inner polygon with the opposite // winding order as the outer polygon. inner2 := plotter.XYs{{X: 3.5, Y: 2.5}, {X: 2.5, Y: 2.5}, {X: 2.5, Y: 3.5}, {X: 3.5, Y: 3.5}} poly, err := plotter.NewPolygon(outer1, inner1, inner2) if err != nil { log.Panic(err) } poly.Color = color.NRGBA{B: 255, A: 255} p := plot.New() p.Title.Text = "Polygon with holes" p.X.Label.Text = "X" p.Y.Label.Text = "Y" p.Add(poly) p.Legend.Add("key", poly) p.Legend.TextStyle.Font.Size = vg.Points(8) p.Legend.TextStyle.Color = color.White p.Legend.ThumbnailWidth = vg.Points(10) // Here we save the image in different file formats // to show how each back end handles polygon holes. // The vgimg backend treats both internal polygons // as holes by default. err = p.Save(100, 100, "testdata/polygon_holes.png") if err != nil { log.Panic(err) } // The vgsvg, vgpdf, and vgeps backgrounds all treat // the internal polygon with the opposite winding // direction as a hole but do not consider the internal // polygon with the same winding direction to be a hole. err = p.Save(100, 100, "testdata/polygon_holes.svg") if err != nil { log.Panic(err) } err = p.Save(100, 100, "testdata/polygon_holes.pdf") if err != nil { log.Panic(err) } err = p.Save(100, 100, "testdata/polygon_holes.eps") if err != nil { log.Panic(err) } } // ExamplePolygon_hexagons creates a heat map with hexagon shapes. // The output of this example is at // https://github.com/gonum/plot/blob/master/plotter/testdata/polygon_hexagons_golden.png. func ExamplePolygon_hexagons() { // hex returns a hexagon centered at (x,y) with radius r. hex := func(x, y, r float64) plotter.XYs { g := make(plotter.XYs, 6) for i := range g { g[i].X = x + r*math.Cos(math.Pi/3*float64(i)) g[i].Y = y + r*math.Sin(math.Pi/3*float64(i)) } return g } var err error p := plot.New() p.Title.Text = "Hexagons" p.X.Label.Text = "X" p.Y.Label.Text = "Y" colorMap := moreland.SmoothBlueRed() colorMap.SetMax(2) colorMap.SetMin(-2) colorMap.SetConvergePoint(0) const ( r = math.Pi / 4 // r is the hexagon radius. // x0 and y0 are the beginning coordinates for the hexagon plot. x0 = 0.0 y0 = 0.0 // nx and ny are the number of hexagons in the x and y directions. nx = 5 ny = 5 ) // dx and dy are the distance between hexgons. dx := 3 * r dy := r * math.Sqrt(3) xstart := []float64{x0, x0 - 1.5*r} ystart := []float64{y0, y0 - r} for i, xmin := range xstart { ymin := ystart[i] x := xmin for ix := 0; ix < nx; ix++ { y := ymin for iy := 0; iy < ny; iy++ { var poly *plotter.Polygon poly, err = plotter.NewPolygon(hex(x, y, r)) if err != nil { log.Panic(err) } poly.Color, err = colorMap.At(math.Sin(x) + math.Sin(y)) if err != nil { log.Panic(err) } poly.LineStyle.Width = 0 p.Add(poly) y += dy } x += dx } } if err = p.Save(100, 100, "testdata/polygon_hexagons.png"); err != nil { log.Panic(err) } }