import matplotlib as mpl
# if want to specify backend, MUST do matplotlib.use() BEFORE importing matplotlib.pyplot
#  (see https://matplotlib.org/faq/usage_faq.html)
# mpl.use("TkAgg")
import matplotlib.pyplot as plt
from matplotlib import colors

import numpy as np
import tensorflow as tf
import time
import sys

class Timer:
    def __init__(self):
        self.perf_start = time.perf_counter()
        self.proc_start = time.process_time()
    def report(self):
        return str(round((time.perf_counter()-self.perf_start),3))
    def reset(self):
        result = self.report()
        self.perf_start = time.perf_counter()
        self.proc_start = time.process_time()
        return result

# def initGraph():
tim1 = Timer()
maxiter = 200
# numpy setup, result Z is 1D array of complex numbers
nY, nX = np.mgrid[-2.0:2.0:0.005, -2.0:2.0:0.005]
nZ = nX+1j*nY
print(type(nZ))
print(nZ.shape)
print("numpy: " + tim1.reset())

# sess.close()
# tf.reset_default_graph()
sess = tf.InteractiveSession()
print("sess startup:", tim1.reset())

tzoom = tf.placeholder(np.complex64, shape=())
toffset = tf.placeholder(np.complex64, shape=())
C = tf.Variable(nZ.astype(np.complex64))
C = C/tzoom + toffset
Z = C
M = tf.Variable(tf.zeros_like(C, tf.float32))

for i in range(maxiter):
    Z = Z*Z + C
    not_diverged = (tf.abs(Z) <= 4)
    M = M + tf.cast(not_diverged, tf.float32)

print("graph setup:", tim1.reset())
tf.global_variables_initializer().run()
print("graph init:", tim1.reset())

# turn off matplotlib toolbar
mpl.rcParams['toolbar'] = 'None'

# DPI, here, has _nothing_ to do with your screen's DPI.
dpi = 80.0
xpixels, ypixels = 800, 800
fig = plt.figure(figsize=(ypixels/dpi, xpixels/dpi), dpi=dpi)
gamma = 0.3
norm = colors.PowerNorm(gamma)

scale = 1.0
zoffset = 0.0 + 0.0j
zscaling = 1.0*scale + 0j
# zoffset = xoff + 1j * yoff
zoffset = 0.0 + 0.0j
result = M.eval(feed_dict={tzoom: zscaling, toffset: zoffset})
result[result >= maxiter] = 0

fimage = fig.figimage(result, cmap='hot', norm=norm)

def onclick(event):
    etim = Timer()
    global zscaling, zoffset
    # print(event)
    if (event.button == 1):
        zscaling = zscaling * 1.2
    elif (event.button == 3):
        zscaling = zscaling * (1.0/1.2)
    result = M.eval(feed_dict={tzoom: zscaling, toffset: zoffset})
    #print(etim.reset())
    rmax = result.max()
    # print(rmax)
    result[result>=maxiter] = 0
    #print(etim.reset())
    fimage.set_data(result)
    #print(etim.reset())
    # fimage.set_data(np.random.random((xpixels, ypixels)))
    plt.draw()
    #print(etim.reset())

def onkey(event):
    global zscaling, zoffset
    key = event.key
    # print('keypress:', event.key)
    sys.stdout.flush()   # is flush of stdout actually needed??
    if key=='a' or key=='left':
        zoffset = zoffset - (0.1 / zscaling)
    elif key=='d' or key=='right':
        zoffset = zoffset + (0.1 / zscaling)
    elif key=='w' or key=='up':
        zoffset = zoffset - (0.1j / zscaling)
    elif key=='s' or key=='down':
        zoffset = zoffset + (0.1j / zscaling)
    result = M.eval(feed_dict={tzoom: zscaling, toffset: zoffset})
    result[result>=maxiter] = 0
    fimage.set_data(result)
    plt.draw()

buttonid = fig.canvas.mpl_connect('button_press_event', onclick)
keyid = fig.canvas.mpl_connect('key_press_event', onkey)

plt.show()

import matplotlib as mpl
# if want to specify backend, MUST do matplotlib.use() BEFORE importing matplotlib.pyplot
#  (see https://matplotlib.org/faq/usage_faq.html)
# mpl.use("TkAgg")
import matplotlib.pyplot as plt
from matplotlib import colors

import numpy as np
import tensorflow as tf
import time
import sys

class Timer:
    def __init__(self):
        self.perf_start = time.perf_counter()
        self.proc_start = time.process_time()
    def report(self):
        return str(round((time.perf_counter()-self.perf_start),3))
    def reset(self):
        result = self.report()
        self.perf_start = time.perf_counter()
        self.proc_start = time.process_time()
        return result

# def initGraph():
tim1 = Timer()
maxiter = 200
# numpy setup, result Z is 1D array of complex numbers
nY, nX = np.mgrid[-2.0:2.0:0.005, -2.0:2.0:0.005]
nZ = nX+1j*nY
print(type(nZ))
print(nZ.shape)
print("numpy: " + tim1.reset())

# sess.close()
# tf.reset_default_graph()
sess = tf.InteractiveSession()
print("sess startup:", tim1.reset())

tzoom = tf.placeholder(np.complex64, shape=())
toffset = tf.placeholder(np.complex64, shape=())
C = tf.Variable(nZ.astype(np.complex64))
C = C/tzoom + toffset
Z = C
M = tf.Variable(tf.zeros_like(C, tf.float32))

for i in range(maxiter):
    Z = Z*Z + C
    not_diverged = (tf.abs(Z) <= 4)
    M = M + tf.cast(not_diverged, tf.float32)

print("graph setup:", tim1.reset())
tf.global_variables_initializer().run()
print("graph init:", tim1.reset())

# turn off matplotlib toolbar
mpl.rcParams['toolbar'] = 'None'

# DPI, here, has _nothing_ to do with your screen's DPI.
dpi = 80.0
xpixels, ypixels = 800, 800
fig = plt.figure(figsize=(ypixels/dpi, xpixels/dpi), dpi=dpi)
gamma = 0.3
norm = colors.PowerNorm(gamma)

scale = 1.0
zoffset = 0.0 + 0.0j
zscaling = 1.0*scale + 0j
# zoffset = xoff + 1j * yoff
zoffset = 0.0 + 0.0j
result = M.eval(feed_dict={tzoom: zscaling, toffset: zoffset})
result[result >= maxiter] = 0

fimage = fig.figimage(result, cmap='hot', norm=norm)

def onclick(event):
    etim = Timer()
    global zscaling, zoffset
    # print(event)
    if (event.button == 1):
        zscaling = zscaling * 1.2
    elif (event.button == 3):
        zscaling = zscaling * (1.0/1.2)
    result = M.eval(feed_dict={tzoom: zscaling, toffset: zoffset})
    #print(etim.reset())
    rmax = result.max()
    # print(rmax)
    result[result>=maxiter] = 0
    #print(etim.reset())
    fimage.set_data(result)
    #print(etim.reset())
    # fimage.set_data(np.random.random((xpixels, ypixels)))
    plt.draw()
    #print(etim.reset())

def onkey(event):
    global zscaling, zoffset
    key = event.key
    # print('keypress:', event.key)
    sys.stdout.flush()   # is flush of stdout actually needed??
    if key=='a' or key=='left':
        zoffset = zoffset - (0.1 / zscaling)
    elif key=='d' or key=='right':
        zoffset = zoffset + (0.1 / zscaling)
    elif key=='w' or key=='up':
        zoffset = zoffset - (0.1j / zscaling)
    elif key=='s' or key=='down':
        zoffset = zoffset + (0.1j / zscaling)
    result = M.eval(feed_dict={tzoom: zscaling, toffset: zoffset})
    result[result>=maxiter] = 0
    fimage.set_data(result)
    plt.draw()

buttonid = fig.canvas.mpl_connect('button_press_event', onclick)
keyid = fig.canvas.mpl_connect('key_press_event', onkey)

plt.show()

# if want to specify backend, MUST do matplotlib.use() BEFORE importing matplotlib.pyplot #  (see https://matplotlib.org/faq/usage_faq.html) # mpl.use("TkAgg") # def initGraph(): # numpy setup, result Z is 1D array of complex numbers # sess.close() # tf.reset_default_graph() # turn off matplotlib toolbar # DPI, here, has _nothing_ to do with your screen's DPI. # zoffset = xoff + 1j * yoff # print(event) #print(etim.reset()) # print(rmax) #print(etim.reset()) #print(etim.reset()) # fimage.set_data(np.random.random((xpixels, ypixels))) #print(etim.reset()) # print('keypress:', event.key) # is flush of stdout actually needed??