# Problem with plotting and printing inside a loop

Hello, there! I’m studying a physical system with the following code:

``````θ = 0.01; dθ = 0.01
ϵ = 1.0
J = 1.0
μ = 1.0
h=0.0
i=1

while θ < 2
m0 = 0.1
while ϵ > 0.001
m = μ*tanh(J/(μ*θ)*m0 + h)
print(m)
ϵ = abs(m-m0)
m0 = m
end
plot!(θ,m)
θ += dθ
end
``````

but neither the prints called by `print(m)` and the plots called by `plot!(θ,m)` are being made. Is there something wrong with the way I’m writing them?

I’m slightly surprised your code doesn’t produce errors (it doesn’t run for me at all, Julia 1.5.3). What version of Julia and Plots.jl are you using? Some comments:

1. I would expect `m` to be local to the `while` loop, and cause an error in the `plot!` unless you had previously defined it in an outer scope. Here’s info about local scopes. Did you already define `m` in REPL?
2. What do you expect from `plot!`? Usually you need to feed it array-like collections, not scalars. Perhaps you mean to add a single point at a time, in which case you might have better success with `plot!([θ],[m])`. Also I am assuming you are `using Plots`?
3. How did you initialize your plot? If your `plot!` works at all, it will just add to an existing plot. You may want to initialize a blank plot with `plt = plot()` before the loop.
4. And if you have a plot that doesn’t display, and it’s been initialized as above, you can do `display(plt)` to make it appear as explained here. But I’m not sure if that’s your problem, since I half expect `m` not to exist in that scope.
5. I have no idea why your `print` doesn’t work, but you may prefer to use `println` to get a newline between outputs.
6. I followed the steps above and got something that ran. My `println` did work, but that inner `while` only iterated twice, so there was not much output. It appears you expect something to converge iteratively, but two iterations will not look very impressive.
7. Would help if you could provide an MWE that runs, or at least errors like expected. And maybe some context about what you’re trying to do and what you expect to happen.
2 Likes

As such, `print(m)` works as long as before the loop you set each time:

``````θ = 0.01
ϵ = 1.0
``````

but you probably want to use `print("\$m ")` or `println(m)` to easily read it.

As said by @apo383 for the plot you need something more and different (and, being only 1 point each time, you should use `scatter!`). So:

``````plot()
while θ < 2
m0 = 0.1
while ϵ > 0.001
m = μ*tanh(J/(μ*θ)*m0 + h)
print("\$m ")
ϵ = abs(m-m0)
m0 = m
end
display(scatter!([θ],[m]))
θ += dθ
end
``````
3 Likes

Hello @apo383 and @davide! Thank you very much! Your suggestions and corrections made it work.
I’m sorry I forgot to made it clear. Yes, I’m using Plots.jl.

1. Corrected that (new code at the end of this reply).
2. I expect to plot, at each cycle, a coordinate pair (θ,m) produced by the calculations.
3. Corrected that.
4. Corrected that as suggested by @davide.
5. `print("\$m ")` works.
6. Yes, the inner loop calculate a iteration that initializes from `m0=0.1`. At the first iteration, for `θ` almost zero, two iterations are enough (I checked myself).

@davide:
That’s a little embarassing, ha! Obviosly the inner loop would only run once, since I was not reinitializing `ϵ = 1.0` at each outter loop.

Now, I present the new code and the plot that I wanted to plot. Just need to figure how to fit a curve instead of a series of points. Once again, thank you very much!

``````using Plots
θ = 0.01; dθ = 0.01
J = 1.0
μ = 1.0
h=0.0
i=1

while θ < 2
m0 = 0.1
m=0
ϵ = 1.0
while ϵ > 0.001
m = μ*tanh(J/(μ*θ)*m0 + h)
ϵ = abs(m-m0)
m0 = m
end
print("\$m ")
if i == 1
display(scatter([θ],[m]))
else
display(scatter!([θ],[m]))
end
θ += dθ
i +=1
end
`````` Might be worth pointing out that if you just want the last plot, there’s no need to call `display` inside the loop. You can display it once at the end:

``````plt = plot()
for ...
...
scatter!(plt, ...)
end
display(plt)  # or just `plt` if in the REPL or running a Jupyter/Juno/VSCode/Pluto cell
``````

If you do want to see an animation of intermediate plots, maybe you should also take a look at the Animations section of the `Plots` manual.

1 Like

Hi @leopdsf

if you do not need animation, you may collect the values (eg. in a matrix or in 2 vectors) inside the loop, and plot it at once when finished, so to have a unique line, using `plot` in this case (and not `scatter`).

2 Likes

Did that ``````θ = 0.01; dθ = 0.00001
J = 1.0
h= 0.0
i= 1
μ = 1.0
lm = 2.0
N = ceil(Int,lm/dθ-1000)
S=zeros(N,2)

while θ < lm
m0 = 0.1
m=0
ϵ = 1.0
while ϵ > 0.0001
m = μ*tanh(J/(μ*θ)*m0 + h)
ϵ = abs(m-m0)
m0 = m
end
#print("\$m ")
S[i,1]=θ
#print("\$m ")
S[i,2]=m
θ += dθ
i +=1
end
``````

Got a nicer graph: 