Search code examples
plothistogramnetlogonormal-distributionagent-based-modeling

How do I plot a distribution curve over a histogram in NetLogo?


I am writing a simple model for the food exchange in bees in NetLogo. I plotted a histogram to show the distribution of bees with different food amounts at each tick. Now I want to plot a normal distribution curve that overlay the histogram, each time I run my model, i.e. a curve that fits the histogram bars. I used one pen with this command to plot my histogram: histogram [food] of turtles and also wrote a function like this to add another pen:

to draw-PDF
  set-current-plot "OVERALL FOOD DISTRIBUTION"
  create-temporary-plot-pen "normal"
  set-plot-pen-color red
  plot-pen-down
  let distsd sqrt ( variance ([food] of turtles) )
  let distmean mean [food] of turtles
  let multconst Number_of_bees / distsd / sqrt(2 * pi)
  let expconst 2 * distsd ^ 2
  let b 0
  while [ b < Number_of_bees]
  [
    let f foodofeachbee b
    let exparg (- ((f - distmean) ^ 2)) / expconst
    let y multconst * exp(exparg)
    plotxy f  y ]
end

foodofeachbee is a reporter that I defined separately. But running this, I got the error that says "your model is too large to run!"

Any suggestions?


Solution

  • You're going to have to modify this code for your specific variables etc, but here's a complete model that demonstrates how to do what I think you want. Copy this code into a blank model and create a plot called Test with a pen that has histogram [ value ] of turtles and interval of 0.05. The code adds a second pen with the pdf constructed from the mean and variance of the variable and adjusted for the number of turtles.

    You are trying to do something with constructing a value for each bee. The pdf has nothing to do with individual bees and the plot procedure can therefore ignore them entirely except to the extent of extracting the values needed for mean and variance.

    turtles-own [value]
    
    to testme
      clear-all
      create-turtles 100
      [ set value random-normal 0.5 0.1 ]
      plot-normalised
      reset-ticks
    end
    
    to plot-normalised
      let meanPlot mean [value] of turtles
      let varPlot variance [value] of turtles
      let mult (count turtles / 20)  / sqrt (2 * pi * varPlot)
      set-current-plot "Test"
      create-temporary-plot-pen "normal"
      set-plot-pen-color red
      plot-pen-down
      let stepper 0.025
      while [ stepper <= 1 ]
      [ plotxy stepper (mult * exp ( - ((stepper - meanPlot) ^ 2) / (2 * varPlot) ) )
        set stepper stepper + 0.05
      ]
    end
    

    Basically, this code calculates the mean and variance of the variable being plotted and feeds specific values of stepper (which is the x coordinate) to the normal distribution pdf function to calculate the y value of the plot.

    What you have to do for your code is replace the interval [0,1] that this code steps through with something like min and max of the variable that you want to plot. In the calculation of the mult value, you can see count turtles / 20. That also needs to be replaced. The 20 is the length of the plotting interval (in this case 1) divided by the width of each histogram bar (in this case 0.05).

    So the last bit of the code will have to look something like:

    let mymin min [value] of turtles
    let mymax max [value] of turtles
    let stepper mymin + 0.025
    while [ stepper <= mymax ]
    [ plotxy stepper (mult * exp ( - ((stepper - meanPlot) ^ 2) / (2 * varPlot) ) )
      set stepper stepper + 0.05
    ]