0

I have a histogram and I want to plot some text on it, which is coming from a dictionary.

Once I have made the histogram using

using Plots 
histogram(data) 

I can put in text by using the command

annotate!(xpos, ypos, text("mytext", :red, :right, 3))

and this works fine. However if I want to loop through a dictionary (of unknown size) and add the values to the plot, something like

for k in keys(MyDict)
    annotate!(xpos, ypos, text(MyDict[k], :red, :right, 3))
end

does nothing. I can manually do it key by key, but why can't I put it in a for loop? I assume that it has something to do with the scope of the for loop. Is there any work around?

Sanushi Salgado
  • 1,195
  • 1
  • 11
  • 18
tyler
  • 11
  • 1

1 Answers1

1

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:

  1. using Plots -> does not return anything worth to visualise
  2. data = rand(100) -> Jupyter will show you the first and last few elements
  3. histogram(data) -> the output will be rendered as an image

A simple histogram of random numbers, shown in Jupyter

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:

annotate!() on a histogram

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

for-loop without return value

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

histogram assigned to a variable

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:

For-loop annotate!() on a histogram

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.

tamasgal
  • 24,826
  • 18
  • 96
  • 135
  • So, your answer can be summarized in a sentence: assign the histogram into a variable and call it after the for loop. – Shayan Apr 08 '23 at 05:52