bell_curve_xy.py

#! /usr/bin/python3
# ===================================================================
# draw a bell curve (normal distribution)
#
# given:
#   bell curve data arithmetic mean
#   bell curve data standard deviation
#   plot x coordinate start value
#   plot x coordinate end value
#   plot x coordinate increment value
#   plot y coordinate maximum value (at peak)
#
# ===================================================================
# Formula used from:
#
#  math.stackexchange.com/questions/1236727/
#  the-x-y-coordinates-for-points-on-a-bell-curve-normal-distribution
#
# ===================================================================
#
# Note (another formula):
#
#  URL = statistics.about.com/od/Formulas/ss/
#             The-Normal-Distribution-Or-Bell-Curve.htm
#
#     y = (1.0/sd*np.sqrt(2.0*np.pi)) * \
#          pow(np.e,-pow(x-m,2.0)/(2.0*sd*sd))
#
# 1. This bell curve formula normalizes the area under the
#    curve to 1.
# 2. All Y values are bell curve formula values and less than 1.
# 3. When plotting, the X values should be scaled.
# 4. When plotting, the Y values should be scaled.
#
# ===================================================================

import numpy as np
import draw_xy_axes as ax
import coordinate_conversion as cc
import user_interface as ui
from graphics import *


# ---- global variables

mean   = 0.0       # bell curve data arithmetic mean (x value)
sd     = 50.0      # bell curve data standard deviation
xstart = -200.0    # plot coordinate x start value
xend   = 200.0     # plot coordinate x end value
xincr  = 10.0      # plot coordinate x increment value
ymax   = 200.0     # plot coordinate y maximum value (at peak)

## some other data to try - asymmetrical plot
##xstart = 100.0
##xend   = 300.0


# -------------------------------------------------------------------
# ---- return the bell curve y value for a given x value
# ---- x     bell curve x value
# ---- ymax  bell curve maximum y value         (y value at peak)
# ---- mean  bell curve data arithmetic mean    (x value)
# ---- sd    bell curve data standard deviation (x value)
# -------------------------------------------------------------------

def BellCurveValue(x,ymax,mean,sd):

    y = ymax * pow(np.e,-pow(x-mean,2.0)/(2.0*sd*sd))

    return y


# -------------------------------------------------------------------
# ---- plot the bell curve
# -------------------------------------------------------------------

def PlotBellCurve(xstart,xend,xincr,ymax,mean,sd):

    win = GraphWin("Bell Curve", 801, 801)
    win.setBackground("white")

    ax.draw_xy_axes(win,True)

    x = xstart                 # starting x coordinate
    
    while x <= xend:           

        y = BellCurveValue(x,ymax,mean,sd)    # calc y coordinate

        ##print(f'x={x} y={y}')

        (wx,wy) = cc.center_to_win_coords(x,y,win.width,win.height)

        ##l = Line(Point(wx,wy),Point(wx+1,wy+1))
        ##l.setWidth(2)
        ##l.setFill('black')
        ##l.draw(win)

        c = Circle(Point(wx,wy),4)
        c.setFill('black')
        c.draw(win)

        x += xincr

    return win                 # next x coordinate


# -------------------------------------------------------------------
# ---- main
# -------------------------------------------------------------------

if __name__ == '__main__':

    # ---- plot bell curve

    win = PlotBellCurve(xstart,xend,xincr,ymax,mean,sd)

    ui.pause()

    win.close()