User:0x0077BE/Code/Digital cliff

Below is the code to generate this digital cliff figure as an SVG.

"""
Generates a graphic which illustrates the "digital cliff" effect from an input function and a step
function.

Licensed under CC-0
"""

from __future__ import division
import numpy as np
from matplotlib import pyplot as plt

# Setup plot parameters
analog_color = 'k'
analog_lw = 2.0

digital_color= '#cc0e0e'
digital_lw = 2.0

figsize = (8, 5)
cdpi = 180

ybuff = 0.025
xbuff = 0.0

# Use a sigmoid curve as the analog function
analog_function = lambda t: 1/(1+np.exp(-t))        # t should be an np.array, w is width param

left_edge = -5                
right_edge = -1*left_edge                           # Currently symmetric, but allow asymmetry

t = np.linspace(left_edge, right_edge, 150)

analog_data = analog_function(t)

fun_max = np.max(analog_data)
fun_min = np.min(analog_data)

transition_level = (fun_max+fun_min)/2                  # Transition occurs halfway to max

transition_t = t[np.argmin(abs(analog_data-transition_level))]

tt = np.array([np.min(t), transition_t, np.max(t)])     # Use these for a step plot
tv = np.array([fun_min, fun_max, fun_max]) 

# Plot the functions
fig = plt.figure(figsize=figsize, dpi=cdpi)
ax = plt.axes(axisbg='none')

analog_h = ax.plot(t, analog_data, '-', color=analog_color, lw=analog_lw)
digital_h = ax.step(tt, tv, '-', color=digital_color, lw=digital_lw, where='post')

x_range = abs(right_edge-left_edge)
y_range = abs(fun_max-fun_min)

plt.xlim(left_edge-xbuff*x_range, right_edge+xbuff*x_range)
plt.ylim(fun_min-0.025*y_range, fun_max+ybuff*y_range)

plt.xticks([])
plt.yticks([])

ann_font_params = {'fontsize':24,
                   'fontstyle':'italic'}

plt.annotate('Digital cliff', 
             xy=(transition_t, 0.85), 
             xytext=(transition_t-0.25, 0.85),
             color=digital_color,
             ha='right',
             va='top',
             **ann_font_params)

ann_x = 0.05*x_range+np.mean([right_edge, left_edge])
ann_y = analog_data[np.argmin(abs(t-ann_x))]

plt.annotate('Analog rolloff', 
             xy=(ann_x, ann_y), 
             xytext=(ann_x+0.5, ann_y),
             color=analog_color,
             ha='left',
             va='center',
             **ann_font_params)

plt.tight_layout()
plt.savefig('Digital-cliff.svg', transparent=True, dpi=cdpi)
plt.show()