# How to plot Newton's method

**URL:** <https://discourse.julialang.org/t/how-to-plot-newtons-method/51160>\
**Category:** Optimization (Mathematical)\
**Tags:** question, plotting, math\
**Created:** [December 3, 2020, 12:59am UTC](https://discourse.julialang.org/t/how-to-plot-newtons-method/51160 "2020-12-03T00:59:22Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![brett\_knoss](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brett_knoss/32/13050_2.png) [@brett\_knoss](https://discourse.julialang.org/u/brett_knoss)\
**Post date:** [December 3, 2020, 12:59am UTC](https://discourse.julialang.org/t/how-to-plot-newtons-method/51160/1 "2020-12-03T00:59:22Z")

</div>

I’m looking at how to plot Newton’s method. I was going to add x values of each itteration, with y=0 to a DataFrame, then run a scatter plot. Is this what I should do, or is there a better way to go about this?

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [December 3, 2020, 1:06am UTC](https://discourse.julialang.org/t/how-to-plot-newtons-method/51160/2 "2020-12-03T01:06:56Z")

</div>

Probably you just need a vector of data. A DataFrame is a unnecessary complication.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [December 4, 2020, 9:56am UTC](https://discourse.julialang.org/t/how-to-plot-newtons-method/51160/3 "2020-12-04T09:56:42Z")

</div>

You could also plot the tangents, like eg this:

> **[Newton's Method Interactive Graph](https://www.intmath.com/applications-differentiation/newtons-method-interactive.php)**
>
> An exploration of Newton's Method for solving non-linear equations.

---

<div class="post-metadata">

**Author:** ![ctkelley](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ctkelley/32/10684_2.png) [@ctkelley](https://discourse.julialang.org/u/ctkelley)\
**Post date:** [December 4, 2020, 11:27am UTC](https://discourse.julialang.org/t/how-to-plot-newtons-method/51160/4 "2020-12-04T11:27:02Z")

</div>

Plotting \log(\| F(x\_n) \|) vs n should tell you what you want to know. Semilog plots are the standard way to do this so you can see what is happening in the terminal phase of the iteration.

If you have a scalar equation and want to plot f(x\_n) vs x\_n, a semilog plot is still the way to go. If you want to plot x\_n vs n, a scatter plot makes sense. You can plot your results with the graph of f(x) as an overlay. This is not as fancy was the moving graph that @Tamas_Papp points to, but is easy to do.

As @lmiq says, a DataFrame is overkill for this.

---

<div class="post-metadata">

**Author:** ![brett\_knoss](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brett_knoss/32/13050_2.png) [@brett\_knoss](https://discourse.julialang.org/u/brett_knoss)\
**Post date:** [December 5, 2020, 9:05pm UTC](https://discourse.julialang.org/t/how-to-plot-newtons-method/51160/5 "2020-12-05T21:05:41Z")

</div>

That’s what I wanted, I’ll go over how to do this. I always forget the formula for a tangent.

```julia
(f(x)-b)/f'(x)=x

```

then I can’t remember how to find b.

---

<div class="post-metadata">

**Author:** ![brett\_knoss](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brett_knoss/32/13050_2.png) [@brett\_knoss](https://discourse.julialang.org/u/brett_knoss)\
**Post date:** [December 5, 2020, 9:09pm UTC](https://discourse.julialang.org/t/how-to-plot-newtons-method/51160/6 "2020-12-05T21:09:00Z")

</div>

That’s interesting. I’m not familiar with semilog plots, and I’m learning linear algebra, so I’m not sure how to write that as code.

As for data frames, I don’t think it’s an issue, but in Maple it creates a crazy large file, so I see where it’s not the best option.

```julia

```

---

<div class="post-metadata">

**Author:** ![brett\_knoss](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brett_knoss/32/13050_2.png) [@brett\_knoss](https://discourse.julialang.org/u/brett_knoss)\
**Post date:** [December 5, 2020, 9:45pm UTC](https://discourse.julialang.org/t/how-to-plot-newtons-method/51160/7 "2020-12-05T21:45:09Z")

</div>

Is a vector a csv? I don’t know how to do data in a matrix.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [December 5, 2020, 9:49pm UTC](https://discourse.julialang.org/t/how-to-plot-newtons-method/51160/8 "2020-12-05T21:49:40Z")

</div>

No, a vector is just a list of numbers. You can crate one with (assuming you are storing numbers):

```julia
x = Float64[]

```

And then add data to it with, for instance,

```julia
push!(x,1.2321)

```

The resulting `x` is what you need to plot something.

---

<div class="post-metadata">

**Author:** ![brett\_knoss](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brett_knoss/32/13050_2.png) [@brett\_knoss](https://discourse.julialang.org/u/brett_knoss)\
**Post date:** [December 5, 2020, 10:45pm UTC](https://discourse.julialang.org/t/how-to-plot-newtons-method/51160/9 "2020-12-05T22:45:56Z")

</div>

> [@lmiq](#):
>
> `push!(x,1.2321)`

thanks.

---

<div class="post-metadata">

**Author:** ![j\_verzani](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/j_verzani/32/8551_2.png) [@j\_verzani](https://discourse.julialang.org/u/j_verzani)\
**Post date:** [December 6, 2020, 2:58am UTC](https://discourse.julialang.org/t/how-to-plot-newtons-method/51160/10 "2020-12-06T02:58:00Z")

</div>

This could be improved, but Makie offers a nice way to explore Newton’s method and its dependence on the initial value. If you install enough packages to get this to run, dragging the initial points shows the method pretty clearly.

```julia
using AbstractPlotting
using AbstractPlotting.MakieLayout
using GLMakie

using ForwardDiff
D(f) = x -> ForwardDiff.derivative(f, float(x))

function newton(f=x->x^5 - x - 1, x0=1, a=-1, b=1.5, n = 20)

    function add_move!(scene, points, pplot)
        idx = Ref(0); dragstart = Ref(false); startpos = Base.RefValue(Point2f0(0))
        on(events(scene).mousedrag) do drag
            if ispressed(scene, Mouse.left)
                if drag == Mouse.down
                    plot, _idx = mouse_selection(scene)
                    if plot == pplot
                        idx[] = _idx; dragstart[] = true
                        startpos[] = to_world(scene, Point2f0(scene.events.mouseposition[]))
                    end
                elseif drag == Mouse.pressed && dragstart[] && checkbounds(Bool, points[], idx[])
                    pos = to_world(scene, Point2f0(scene.events.mouseposition[]))
                    
                    # we work with components, not vector
                    x,y = pos
                    
                    ptidx = idx[]
                    
                    x = clamp(x, a, b)
                    y = zero(y)
                    points[][idx[]] = [x,y]
                    
                    points[] = points[]
                end
            else
                dragstart[] = false
            end
            return
        end
    end

    start_point = Node(Point2f0[(x0, 0)])
    points = lift(start_point) do x₀
        xs = [x₀[1][1]]
        for i in 1:n
            xᵢ₋₁ = xs[end]
            xᵢ = xᵢ₋₁ - f(xᵢ₋₁) /D(f)(xᵢ₋₁)
            push!(xs, xᵢ)
        end
        xs
    end

    plt_points = lift(points) do pts
        xs = Float64[]
        ys = Float64[]
        for i in 1:length(pts)-1
            pᵢ, pᵢ₊₁ = pts[i], pts[i+1]
            append!(xs, [pᵢ, pᵢ, pᵢ₊₁])
            append!(ys, [0, f(pᵢ), 0])
        end
        (xs, ys)
    end

    scene = Scene()
    lines!(scene, a..b, f, linewidth=5, color=:blue)
    lines!(scene, a..b, zero, color=:red)
    lines!(scene, plt_points, color=:black, linewidth=2)
    scatter!(scene, start_point, color=:red)

    add_move!(scene, start_point, scene[end])

    scene
end

```

---

<div class="post-metadata">

**Author:** ![brett\_knoss](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brett_knoss/32/13050_2.png) [@brett\_knoss](https://discourse.julialang.org/u/brett_knoss)\
**Post date:** [December 6, 2020, 4:04am UTC](https://discourse.julialang.org/t/how-to-plot-newtons-method/51160/11 "2020-12-06T04:04:42Z")

</div>

I ran it. I get warnings from packages but no errors. Is it supposed to output a plot?

---

<div class="post-metadata">

**Author:** ![j\_verzani](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/j_verzani/32/8551_2.png) [@j\_verzani](https://discourse.julialang.org/u/j_verzani)\
**Post date:** [December 6, 2020, 4:35am UTC](https://discourse.julialang.org/t/how-to-plot-newtons-method/51160/12 "2020-12-06T04:35:12Z")

</div>

Try: newton()

---

<div class="post-metadata">

**Author:** ![brett\_knoss](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brett_knoss/32/13050_2.png) [@brett\_knoss](https://discourse.julialang.org/u/brett_knoss)\
**Post date:** [December 6, 2020, 4:40am UTC](https://discourse.julialang.org/t/how-to-plot-newtons-method/51160/13 "2020-12-06T04:40:58Z")

</div>

scatter! not defined.

It might be missing a package, or that could be a syntax error.

---

<div class="post-metadata">

**Author:** ![j\_verzani](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/j_verzani/32/8551_2.png) [@j\_verzani](https://discourse.julialang.org/u/j_verzani)\
**Post date:** [December 6, 2020, 4:43am UTC](https://discourse.julialang.org/t/how-to-plot-newtons-method/51160/14 "2020-12-06T04:43:36Z")

</div>

That’s from AbstractPlotting, or should be.

---

<div class="post-metadata">

**Author:** ![brett\_knoss](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brett_knoss/32/13050_2.png) [@brett\_knoss](https://discourse.julialang.org/u/brett_knoss)\
**Post date:** [December 6, 2020, 4:47am UTC](https://discourse.julialang.org/t/how-to-plot-newtons-method/51160/15 "2020-12-06T04:47:34Z")

</div>

Ok, I’m using Jupyter, does it matter if the using commands are in the same code chunk as other code?

I get the scatter not defined error when I run

Try:newton()

---

<div class="post-metadata">

**Author:** ![j\_verzani](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/j_verzani/32/8551_2.png) [@j\_verzani](https://discourse.julialang.org/u/j_verzani)\
**Post date:** [December 6, 2020, 5:05am UTC](https://discourse.julialang.org/t/how-to-plot-newtons-method/51160/16 "2020-12-06T05:05:41Z")

</div>

I only ran from a terminal. I’m not sure, but WGLMakie might work in place of GLMakie.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [December 6, 2020, 9:19am UTC](https://discourse.julialang.org/t/how-to-plot-newtons-method/51160/17 "2020-12-06T09:19:38Z")

</div>

> [@brett\_knoss](#):
>
> I can’t remember how to find b.

For an x, given f(x) and f'(x), if you want the tangent as y = a + bx, then just match values and derivatives, ie f(x) = a + bx and f'(x) = b, obtaining a = f(x) - x f'(x).

---

<div class="post-metadata">

**Author:** ![brett\_knoss](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brett_knoss/32/13050_2.png) [@brett\_knoss](https://discourse.julialang.org/u/brett_knoss)\
**Post date:** [December 6, 2020, 5:26pm UTC](https://discourse.julialang.org/t/how-to-plot-newtons-method/51160/18 "2020-12-06T17:26:57Z")

</div>

> [@j\_verzani](#):
>
> ```julia
> D(f) = x -> ForwardDiff.derivative(f, float(x))
> 
> function newton(f=x->x^5 - x - 1, x0=1, a=-1, b=1.5, n = 20)
> 
> function add_move!(scene, points, pplot)
> idx = Ref(0); dragstart = Ref(false); startpos = Base.RefValue(Point2f0(0))
> on(events(scene).mousedrag) do drag
> if ispressed(scene, Mouse.left)
> if drag == Mouse.down
> plot, _idx = mouse_selection(scene)
> if plot == pplot
> idx[] = _idx; dragstart[] = true
> startpos[] = to_world(scene, Point2f0(scene.events.mouseposition[]))
> end
> elseif drag == Mouse.pressed && dragstart[] && checkbounds(Bool, points[], idx[])
> pos = to_world(scene, Point2f0(scene.events.mouseposition[]))
>                     
> # we work with components, not vector
> x,y = pos
>                     
> ptidx = idx[]
>                     
> x = clamp(x, a, b)
> y = zero(y)
> points[][idx[]] = [x,y]
>                     
> points[] = points[]
> end
> else
> dragstart[] = false
> end
> return
> end
> end
> 
> start_point = Node(Point2f0[(x0, 0)])
> points = lift(start_point) do x₀
> xs = [x₀[1][1]]
> for i in 1:n
> xᵢ₋₁ = xs[end]
> xᵢ = xᵢ₋₁ - f(xᵢ₋₁) /D(f)(xᵢ₋₁)
> push!(xs, xᵢ)
> end
> xs
> end
> 
> plt_points = lift(points) do pts
> xs = Float64[]
> ys = Float64[]
> for i in 1:length(pts)-1
> pᵢ, pᵢ₊₁ = pts[i], pts[i+1]
> append!(xs, [pᵢ, pᵢ, pᵢ₊₁])
> append!(ys, [0, f(pᵢ), 0])
> end
> (xs, ys)
> end
> 
> scene = Scene()
> lines!(scene, a..b, f, linewidth=5, color=:blue)
> lines!(scene, a..b, zero, color=:red)
> lines!(scene, plt_points, color=:black, linewidth=2)
> scatter!(scene, start_point, color=:red)
> 
> add_move!(scene, start_point, scene[end])
> 
> scene
> end
> 
> ```

```julia

```

using Plots  
using ForwardDiff  
f(x)=((x)^6)-2  
fp(x)= ForwardDiff.derivative(f, x)  
t(x)=-1\*(f(x)-x_fp(x)+fp(x))  
P1=plot(f,1:.001:1.55,legend=false);hline!([0])  
for i in 1:9  
root=x  
x=BigFloat(x)-BigFloat(f(x)/fp(x))  
e=BigFloat(abs((x)-(root)))  
push!(df,(x,e,f(x)))  
t(x)=-(f(root)-x_fp(root)+fp(root))  
plot!(t,1:.001:1.55)  
vline!([root])  
end

```julia
this gives me lines with the correct slope, but they don't move with root or x, to be tangents.
```

---

<div class="post-metadata">

**Author:** ![j\_verzani](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/j_verzani/32/8551_2.png) [@j\_verzani](https://discourse.julialang.org/u/j_verzani)\
**Post date:** [December 6, 2020, 7:40pm UTC](https://discourse.julialang.org/t/how-to-plot-newtons-method/51160/19 "2020-12-06T19:40:29Z")

</div>

Okay, this should work in Jupyter. The `@manipulate` macro from `SimplePlots` allows the interaction with the initial point.

```julia
using Plots, Interact
using ForwardDiff
D(f) = x -> ForwardDiff.derivative(f, float(x))
f(x) = x^5 - x - 1
a, b = -1.5, 1.5
nsteps = 20
@manipulate for x0=slider(a:0.1:b, value=1.0, label="x0")
    ts = range(a, b, length=251)
    plot(ts, f.(ts), xlim=(a,b), ylim=(-5,5), legend=false)
    plot!(ts, 0 .* ts) 
    scatter!([x0],[0])

    xs = Float64[]
    ys = Float64[]
    for i in 1:nsteps
        x1 = x0 - f(x0)/D(f)(x0)
        append!(xs, [x0, x0, x1])
        append!(ys, [0,f(x0), 0])
        x0 = x1
    end

    plot!(xs, ys)

end

```

[Edited to use Plots+Interact]

---

<div class="post-metadata">

**Author:** ![brett\_knoss](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brett_knoss/32/13050_2.png) [@brett\_knoss](https://discourse.julialang.org/u/brett_knoss)\
**Post date:** [December 6, 2020, 8:53pm UTC](https://discourse.julialang.org/t/how-to-plot-newtons-method/51160/20 "2020-12-06T20:53:53Z")

</div>

> [@j\_verzani](#):
>
> ```julia
> using SimplePlots
> using ForwardDiff
> D(f) = x -> ForwardDiff.derivative(f, float(x))
> f(x) = x^5 - x - 1
> a, b = -1.5, 1.5
> nsteps = 20
> @manipulate for x0=slider(a:0.1:b, value=1.0, label="x0")
> plot(f, a, b, xlim=(a,b), ylim=(-5,5))
> scatter!([x0],[0])
> 
> xs = Float64[]
> ys = Float64[]
> for i in 1:nsteps
> x1 = x0 - f(x0)/D(f)(x0)
> append!(xs, [x0, x0, x1])
> append!(ys, [0,f(x0), 0])
> x0 = x1
> end
> 
> plot!(xs, ys)
> 
> end
> 
> ```

I,m getting slider not defined

```julia
UndefVarError: slider not defined

Stacktrace:
 [1] top-level scope at C:\Users\Brett\.julia\packages\SimplePlots\6y94O\src\interact\gui.jl:39
 [2] include_string(::Function, ::Module, ::String, ::String) at .\loading.jl:1091

```

[Next page](https://discourse.julialang.org/t/how-to-plot-newtons-method/51160.md?page=2)
