I assume you are working in a Jupyter notebook, at least this is the only scenario I can imagine to make sense of your observations ;)
One important thing to realise (and this is independent of Julia, it's just the way Jupyter, or any other REPL usually works) is that Jupyter tries to visualise the input of the cell by taking the output of the cell, which is essentially what the last expression in the cell returns. This might sound confusing, so let me show an example based on yours.
You see three cells below:
using Plots
-> does not return anything worth to visualise
data = rand(100)
-> Jupyter will show you the first and last few elements
histogram(data)
-> the output will be rendered as an image

Now coming back to your problem: if you do histogram(data)
, you will be presented a histogram, just like in the example above, since histogram(data)
returns something with Jupyter can display as an image.
If you use annotate!(...)
, it will act on the last plot you created (which is your histogram) and it will re-return it which Jupyter can display, so you'll see the annotated histogram:

Now coming to the for-loop: they do not return anything, so Jupyter will not be able to display anything

What you want is: creating a variable to access your initial histogram, called e.g. fig
:

notice that an assignment in Julia returns the right-hand side, so that Jupyter displays the histogram in this case.
Now you can use whatever mutating function (like annotate!()
) in as many for-loops as you want and then just give Jupyter the fig
object to display:

Note that if you are not in a Jupyter environment, you can use show(fig)
to display it, or better: savefig(fig, "filename.png")
(or whatever image extension you prefer) to save the plot.