Skip to content

Instantly share code, notes, and snippets.

@juhasch
Created October 11, 2012 17:53
Show Gist options
  • Save juhasch/3874297 to your computer and use it in GitHub Desktop.
Save juhasch/3874297 to your computer and use it in GitHub Desktop.
xkcd-ify a plot
from pylab import *
import scipy.signal as signal
from scipy.stats import norm
import matplotlib.font_manager as fm
def rand_func(data):
""" multiply data by low-pas filtered random values
data - input data array
"""
length=size(data)
coeffs = norm.rvs(loc = 0, scale = 1e-2, size = length) # random values
b = signal.firwin(80, min(1,30./length))
response = signal.lfilter(b,1,coeffs)+1 # use low pass filter to smooth variations
return data*response
def make_xkcd(ax,x_label='',y_label=''):
""" make an xkcd style plot
ax - axis element
x_label, y_label - optional text for x and y axis
"""
# add randomness to x and y of plotted lines
pltlist=ax.get_lines()
for p in pltlist:
x = p.get_xdata()
y = p.get_ydata()
x = rand_func(x)
y = rand_func(y)
p.set_xdata(x)
p.set_ydata(y)
ax.axison = False
# get boundaries for x and y axis
xmin, xmax = ax.get_xlim()
ymin, ymax = ax.get_ylim()
xsize=xmax-xmin
ysize=ymax-ymin
# Increase figure size to fit new custom axes
BORDER=10. # border size
xmin -=xsize/BORDER
xmax +=xsize/BORDER
ymin -=ysize/BORDER
ymax +=ysize/BORDER
ax.set_xlim(xmin, xmax)
ax.set_ylim(ymin, ymax)
# Poor man's x-axis
xlen=size(x)
xaxis = linspace(xmin,xmax-xsize/BORDER,xlen)
yaxis = rand_func([ysize] * xlen)-ysize+ymin+ysize/BORDER
ax.plot(xaxis, yaxis, 'k', lw=2)
ax.arrow(xaxis[-1], yaxis[-1], 1e-6, 0, fc='k', lw=2, head_width=ysize/30, head_length=xsize/BORDER)
# Poor man's y-axis
xaxis = rand_func([xsize] * xlen)-xsize+xmin+xsize/BORDER
yaxis = linspace(ymin,ymax-ysize/BORDER,xlen)
ax.plot(xaxis, yaxis, 'k', lw=2)
ax.arrow(xaxis[-1], yaxis[-1],0, 1e-6, fc='k', lw=2, head_width=xsize/40, head_length=ysize/BORDER);
# Add axis description text
# The font is available here: http://antiyawn.com/uploads/Humor-Sans.ttf
prop = fm.FontProperties(fname='c://windows/fonts/Humor-Sans.ttf')
a=ax.text(xmax, ymin, x_label, fontproperties=prop, size=14,rotation=2,horizontalalignment='right')
ax.text(xmin, ymax, y_label, fontproperties=prop, size=14, rotation=88,verticalalignment='top');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment