Skip to content

Allows function plotting to work with discontinuous functions.

Sebastien Binet requested to merge justincinmd:master into master

Created by: justincinmd

Consider the function sqrt(x^2 - 1), graphed as follows:

package main

import (
        "image/color"
        "math"

        "github.com/gonum/plot"
        "github.com/gonum/plot/plotter"
        "github.com/gonum/plot/vg"
)

func main() {
        p, err := plot.New()
        if err != nil {
                panic(err)
        }
        p.Title.Text = "Functions"
        p.X.Label.Text = "X"
        p.Y.Label.Text = "Y"

        // A quadratic function x^2
        discont := plotter.NewFunction(func(x float64) float64 { return math.Sqrt(x*x - 1) })
        discont.Color = color.RGBA{B: 255, A: 255}
        discont.Samples = 200

        // Add the functions and their legend entries.
        p.Add(discont)
        p.Legend.Add("sqrt(x^2 - 1)", discont)
        p.Legend.ThumbnailWidth = 0.5 * vg.Inch

        // Set the axis ranges.  Unlike other data sets,
        // functions don't set the axis ranges automatically
        // since functions don't necessarily have a
        // finite range of x and y values.
        p.X.Min = -3
        p.X.Max = 3
        p.Y.Min = -1
        p.Y.Max = 3

        // Save the plot to a PNG file.
        if err := p.Save(4*vg.Inch, 4*vg.Inch, "functions.png"); err != nil {
                panic(err)
        }
}

In master, this code will infinite loop, because the function returns NaN for x values between -1 and 1, where the solution isn't a real number.

Instead of plotting all of the sample points at once, my change plots each continuous section of real-number solutions independently, allowing for discontinuous functions. Running the inline code with my change creates this graph:

functions

Merge request reports

Loading