October 18, 2014 Stardate: 68261.5 Tagged as: Python Matplotlib
This is my attempt at recreating the small multiples graph from Flowingdata in matplotlib. I realize the point of the flowingdata article was to showcase filtering and linking using D3.js - but wanted to simply create the chart.
You can download the code in this gist
%matplotlib inline
import matplotlib.pyplot as plt
#from matplotlib import gridspec #http://matplotlib.org/users/gridspec.html\
import pandas as pd
import matplotlib.ticker as mticker
data = pd.DataFrame.from_csv('/home/joe/Python/Projects/smallMultiples/askmefi_category_year.tsv', sep='\t')
categories = data.category.unique()
mydata = {}
for i in categories:
mydata[i] = data[data.category==i]
mydata[categories[0]].head()
nrows = 4; ncols = 5
num_plots = nrows * ncols # number of subplots
assert num_plots == len(mydata)
figwidth = 13/1.1
figheight = 10/1.2
x_range = range(2004,2015,1)
fig = plt.figure(figsize=(figwidth, figheight))
#fig = plt.figure()
# create the subplot figure
axes = [plt.subplot(nrows,ncols,i) for i in range(1,num_plots+1)]
# h_pad is horizontal padding between subplots
# w_pad is vertical padding between subplots
plt.tight_layout(pad=0, w_pad=3, h_pad=3)
#plt.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=0.01)
plt.subplots_adjust(hspace=1)
plt.rcParams['xtick.major.pad']='8'
for i in range(len(categories)):
ax = axes[i]
y = data["n"][data.category==categories[i]]
x = x_range
ax.plot(x,y,color='#222222')
ax.fill_between(x,y,0,color='#cec6b9')
#ax.xticks(['2004','2014'])
ax.set_ylim([0,3000])
ax.set_xlim([2004,2014])
# Remove top and right axes and ticks
ax.spines['top'].set_visible(False)
ax.spines['bottom'].set_visible(False)
ax.spines['left'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.yaxis.set_ticks_position('none')
ax.xaxis.set_ticks_position('none')
#ax.xticks([0,1], ['2004','2014'], rotation='horizontal')
# Find at most 101 ticks on the y-axis at 'nice' locations
max_yticks = 3
yloc = plt.MaxNLocator(max_yticks)
ax.yaxis.set_major_locator(yloc)
#max_xticks = 4
#xloc = plt.MaxNLocator(max_xticks)
#ax.xaxis.set_major_locator(xloc)
ax.set_xticklabels(['2004','','','','','2014'])
ax.set_xlabel(categories[i])
ax.tick_params(axis='both', which='major', labelsize=8)
def func(x, pos): # formatter function takes tick label and tick position
s = '{:0,d}'.format(int(x))
return s
ax.yaxis.set_major_formatter(mticker.FuncFormatter(func))
plt.show()
%reload_ext version_information
%version_information ipython, pandas, matplotlib