
# animLogCobweb.py
# input: 2.5 or 3.2 or 3.5 or 3.56 or 3.84 or 4

'''
# https://ipython-books.github.io/121-plotting-the-bifurcation-diagram-of-a-chaotic-dynamical-system/

# Chaos and Fractals", David Feldman, Ch. 9

Based on logCobweb.py

'''


import sys
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider
from frange import *


EPS = 0.0001
MAX_ORBITS = 30


def logistic(r, x):
  return r * x * (1 - x)


def update(r):
  drawGraph(r)
  fig.canvas.draw_idle()


def drawGraph(r):
  # Plot the logistic map in ax1
  ax1.clear()
  ax2.clear()
  vals = [logistic(r, t) for t in ts]
  ax1.plot(ts, vals, 'k', lw=2)
  ax1.plot([0, 1], [0, 1])  # add the y=x line
  
  x =  0.1
  xs = [x]
  prevX = 1000 # dummy 
  i = 0
  while (i < MAX_ORBITS) and (abs(x-prevX) > EPS):
    # print(i, f"{x:0.3f}")
    y = logistic(r, x)
  
    # plot lines between fn and y=x:
    ax1.plot([x, x], [x, y], 'k', ls='dashed') # vertical
    ax1.plot([x, y], [y, y], 'k', ls='dashed') # horizontal
    ax1.plot([x], [y], 'or', ms=5) # intersection pt
    prevX = x
    x = y
    xs.append(x)
    i += 1
  
  ax1.set_xlim(0, 1)
  ax1.set_ylim(0, 1)
  ax1.set_xlabel("x_n")
  ax1.set_ylabel("x_n+1")
  ax1.set_title(f"Logistic map (r={r:.4f})")

  # ----------------
  
  # Plot changes of x values
  tms = [t for t in range(len(xs))]
  ax2.plot(tms, xs, 'bo-')
  ax2.set_xlabel("n")
  ax2.set_ylabel("x_n")
  ax2.set_title("Time Series for x_n")

  


fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 6))
plt.subplots_adjust(bottom=0.25)

ts = linspace(0, 1)
r = 2.5
drawGraph(r)

# r slider
rAxis = plt.axes([0.15, 0.1, 0.65, 0.03])
rSlider = Slider(rAxis, 'r', 0, 4, valinit=r, valfmt='%0.4f')
                          # min, max, initial value
rSlider.on_changed(update)
rAxis.add_artist(rAxis.xaxis)

plt.show()
