In [1]:
%%javascript
$.getScript('https://kmahelona.github.io/ipython_notebook_goodies/ipython_notebook_toc.js')
In [2]:
from IPython.core.display import display, HTML
display(HTML("<style>.container { width:70em !important; }</style>"))
# displaydisplay(HTML("<style>.container { width:79em !important; }</style>"))
In [3]:
import pandas as pd
import numpy as np
%matplotlib inline
plt.rcParams['figure.figsize'] = (15, 5)
Read this and you'll know everything about matplotlib.
In [75]:
"""
Author: Piotr A. Zolnierczuk (zolnierczukp at ornl dot gov)
Based on a paper by:
Drawing an elephant with four complex parameters
Jurgen Mayer, Khaled Khairy, and Jonathon Howard,
Am. J. Phys. 78, 648 (2010), DOI:10.1119/1.3254017
"""
import numpy as np
import pylab
# elephant parameters
p1, p2, p3, p4 = (50 - 30j, 18 + 8j, 12 - 10j, -14 - 60j )
p5 = 40 + 20j # eyepiece
def fourier(t, C):
f = np.zeros(t.shape)
A, B = C.real, C.imag
for k in range(len(C)):
f = f + A[k]*np.cos(k*t) + B[k]*np.sin(k*t)
return f
def elephant(t, p1, p2, p3, p4, p5):
npar = 60j
Cx = np.zeros((npar,), dtype='complex')
Cy = np.zeros((npar,), dtype='complex')
Cx[1] = p1.real*1j
Cx[2] = p2.real*1j
Cx[3] = p3.real
Cx[5] = p4.real
Cy[1] = p4.imag + p1.imag*1j
Cy[2] = p2.imag*1j
Cy[3] = p3.imag*1j
x = np.append(fourier(t,Cx), [-p5.imag])
y = np.append(fourier(t,Cy), [p5.imag])
return x,y
x, y = elephant(np.linspace(0,2*np.pi,1000), p1, p2, p3, p4, p5)
pylab.plot(y,-x,'.')
pylab.plot(-y + 200, -x, '.')
pylab.show()
In [5]:
for _ in range(10):
display(HTML("<br />"))
Okay, let's go:
In [19]:
display(HTML("<a id='fancyplot'>"))
hist_data = pd.DataFrame(np.random.exponential(3.3, size=10000), columns=['data']).astype(int)
hist_data = hist_data['data'].value_counts()
pie_data = pd.Series(np.repeat(hist_data.index == 0, hist_data.values)).value_counts()
box_data = hist_data.copy()
digit_data = box_data.apply(lambda x: len(str(x)))
hist_data = pd.DataFrame(hist_data)
hist_data.loc[0, 'data2'] = hist_data.loc[0, 'data']
hist_data.loc[0, 'data'] = np.nan
from matplotlib.ticker import ScalarFormatter
scalar_formatter = ScalarFormatter(useMathText=True)
scalar_formatter.set_powerlimits((3,3))
gs = plt.GridSpec(2, 3, width_ratios=(1, 5, 1), height_ratios=(5,2))
f = plt.figure(figsize=(20,15))
ax1 = f.add_subplot(gs[0, 0])
ax2 = f.add_subplot(gs[0, 1:])
ax3 = f.add_subplot(gs[1,:2])
ax4 = f.add_subplot(gs[1, 2])
pie_data.plot.pie(ax=ax1,
labels=('Yea', 'Nay'), explode=(0,0.2), shadow=True,autopct='%1.1f%%', startangle=90)
hist_data.plot.bar(ax=ax2,
rot=0, legend=False)
ax3.scatter(box_data.index, box_data.values, marker='*', cmap='viridis',
s=300*box_data.apply(lambda x: (x % 7) + 1), c=box_data.apply(lambda x: (x % 5) + 1), alpha=0.6)
box_data.plot.box(whis=5.5, ax=ax4, showmeans=True, meanline=True, notch=True, sym='*', bootstrap=10000)
# Pie Data
ax1.set_title('customer has friends\n (which have used login via App)')
ax1.set_ylabel('')
# Hist
ax2.set_title('Friends per Customer')
ax2.set_xlabel("Number of Friends")
ax2.set_ylabel("Number of Customers")
ax2.yaxis.set_major_formatter(scalar_formatter) #fancy formatting
# Boxplot
ax4.xaxis.set_ticklabels('')
f.suptitle("Facebook Friends Analysis", fontsize=22)
# BG white
ax2.set_facecolor('white')
ax3.set_facecolor('white')
ax4.set_facecolor('white')
# Special Axis Stuff
ax1.axis("equal")
ax3.axis("off")
ax4.yaxis.tick_right() # axis to the right side
ax2.grid(True, which='major', color='lightgrey')
ax4.grid(True, which='major', color='lightgrey')
gs.tight_layout(f, rect=(0,0,1,0.95))
f.savefig("figures/facebook_friends_example.svg")
display(HTML("</a>"))
In [39]:
pd.DataFrame(np.random.exponential(4, size=10000), columns=['data']).astype(int).hist()
Out[39]:
In [21]:
hist_data = pd.DataFrame(np.random.exponential(4, size=10000), columns=['data']).astype(int)
hist_data = hist_data['data'].value_counts()
hist_data.head()
Out[21]:
In [23]:
hist_data.plot()
Out[23]:
In [24]:
pie_data = pd.Series(np.repeat(hist_data.index == 0, hist_data.values)).value_counts()
# Hacky Trick, just to get True X times and False Y times, with X number of customers without friends and Y number of customers with friends
pie_data
Out[24]:
In [25]:
pie_data.plot.pie(figsize=(5,5))
Out[25]:
In [63]:
box_data = hist_data.copy()
hist_data = pd.DataFrame(hist_data)
hist_data.loc[0, 'data2'] = hist_data.loc[0, 'data']
hist_data.loc[0, 'data'] = np.nan
hist_data.head()
Out[63]:
In [28]:
hist_data.plot(style='.-', markersize=20)
Out[28]:
Not so special, isn't it?
In [40]:
hist_data
Out[40]:
In [47]:
ax = hist_data.plot.bar()
for data in hist_data.iteritems():
ax.text(data[0]+0.2, data[1]+0.3, data[1], fontsize=16)
In [17]:
hist_data.fillna(1000).plot.bar()
Out[17]:
Ahh, there we go.
Finally we have scatter and Boxplots:
In [320]:
plt.scatter(box_data.index, box_data.values)
Out[320]:
In [319]:
box_data.plot.box()
Out[319]:
In [277]:
ax0 = plt.subplot(121)
ax1 = plt.subplot(122)
# Wow, i don't want to do this, when creating more and more subplots
pie_data.plot.pie(ax=ax0)
hist_data.plot.bar(ax=ax1)
Out[277]:
In [53]:
fig = plt.figure(figsize=(20,5))
ax0 = fig.add_subplot(121)
ax1 = fig.add_subplot(122)
# Same here, not economical
pie_data.plot.pie(ax=ax0)
hist_data.plot.bar(ax=ax1)
Out[53]:
In [279]:
fig, ax = plt.subplots(1, 2, figsize=(20,5))
# much better! yea!
pie_data.plot.pie(ax=ax[0])
hist_data.plot.bar(ax=ax[1])
Out[279]:
In [280]:
fig, ax = plt.subplots(1, 2, figsize=(20,5), gridspec_kw = {'width_ratios':[1,5]})
# much better! yea!
pie_data.plot.pie(ax=ax[0])
hist_data.plot.bar(ax=ax[1])
Out[280]:
So, this is one row... but we saw multiple rows and columns, let's try this:
In [281]:
fig, ax = plt.subplots(2, 2, figsize=(20,5), gridspec_kw = {'width_ratios':[1,3]})
# much better! yea!
pie_data.plot.pie(ax=ax[0, 0])
hist_data.plot.bar(ax=ax[0, 1])
# important: this works also fine, instead of using the pandas routine which is kind of a wrapper, we give the object to the matplotlib routine directly
ax[1,0].scatter(box_data.index, box_data.values)
box_data.plot.box(ax=ax[1,1])
Out[281]:
Fine, this is all of our data now... but how to make it look like [the first plot](#fancyplot)?
In [282]:
gs = plt.GridSpec(1, 2, width_ratios=(1,5))
f = plt.figure(figsize=(20,5))
ax1 = f.add_subplot(gs[0])
ax2 = f.add_subplot(gs[1])
ax1.axis("equal")
pie_data.plot.pie(ax=ax1)
hist_data.plot.bar(ax=ax2)
Out[282]:
Cool, very easy... but not that's not enough:
In [55]:
gs = plt.GridSpec(2, 3, width_ratios=(1,5, 1))
f = plt.figure(figsize=(20,5))
ax1 = f.add_subplot(gs[0, 0])
ax2 = f.add_subplot(gs[0, 1:])
ax3 = f.add_subplot(gs[1, :2])
ax4 = f.add_subplot(gs[1, 2])
pie_data.plot.pie(ax=ax1)
hist_data.plot.bar(ax=ax2)
box_data.plot(style='.', markersize=20, ax=ax3)
box_data.plot.box(ax=ax4)
f.suptitle("Facebook Friends Analysis", fontsize=22)
Out[55]:
In [284]:
pie_data.plot.pie()
Out[284]:
In [56]:
pie_data
Out[56]:
In [60]:
pie_data.plot.pie(labels=('Yea', 'Nay'), explode=(0, 0.2), shadow=True,autopct='%1.1f%%', startangle=90)
ax1 = plt.gca()
ax1.axis("equal")
ax1.set_title('customer has friends\n (which have used login via App)')
ax1.set_ylabel('')
Out[60]:
In [65]:
hist_data.plot.bar()
Out[65]:
In [64]:
from matplotlib.ticker import ScalarFormatter
scalar_formatter = ScalarFormatter(useMathText=True)
scalar_formatter.set_powerlimits((3,3))
hist_data.plot.bar(rot=0, legend=False)
ax2 = plt.gca()
# Hist
ax2.set_title('Friends per Customer')
ax2.set_xlabel("Number of Friends")
ax2.set_ylabel("Number of Customers")
# Digit Data
ax2.set_facecolor('white') # whitesmoke
ax2.grid(True, which='major', color='lightgrey')
ax2.yaxis.set_major_formatter(scalar_formatter) #fancy formatting
In [288]:
plt.scatter(box_data.index, box_data.values)
Out[288]:
In [70]:
plt.scatter(box_data.index, box_data.values, marker='*', cmap='viridis',
s=300*box_data.apply(lambda x: (x % 7) + 1),
c=box_data.apply(lambda x: (x % 5) + 1),
alpha=0.6)
ax3 = plt.gca()
ax3.set_facecolor('white') # whitesmoke
ax3.axis("off")
Out[70]:
In [290]:
box_data.plot.box()
Out[290]:
In [72]:
plt.boxplot(box_data.values, whis=1.5, showmeans=True, meanline=True, notch=True, sym='*', bootstrap=10000)
ax4 = plt.gca()
ax4.set_facecolor('white') # whitesmoke
ax4.yaxis.tick_right()
ax4.grid(color='lightgrey')
ax4.xaxis.set_ticklabels('')
Out[72]:
In [ ]:
In [ ]:
In [ ]:
In [ ]:
In [73]:
hist_data = pd.DataFrame(np.random.exponential(3.3, size=10000), columns=['data']).astype(int)
hist_data = hist_data['data'].value_counts()
pie_data = pd.Series(np.repeat(hist_data.index == 0, hist_data.values)).value_counts()
box_data = hist_data.copy()
digit_data = box_data.apply(lambda x: len(str(x)))
hist_data = pd.DataFrame(hist_data)
hist_data.loc[0, 'data2'] = hist_data.loc[0, 'data']
hist_data.loc[0, 'data'] = np.nan
from matplotlib.ticker import ScalarFormatter
scalar_formatter = ScalarFormatter(useMathText=True)
scalar_formatter.set_powerlimits((3,3))
gs = plt.GridSpec(2, 3, width_ratios=(1, 5, 1), height_ratios=(5,2))
f = plt.figure(figsize=(20,10))
ax1 = f.add_subplot(gs[0, 0])
ax2 = f.add_subplot(gs[0, 1:])
ax3 = f.add_subplot(gs[1,:2])
ax4 = f.add_subplot(gs[1, 2])
pie_data.plot.pie(ax=ax1,
labels=('Yea', 'Nay'), explode=(0,0.2), shadow=True,autopct='%1.1f%%', startangle=90)
hist_data.plot.bar(ax=ax2,
rot=0, legend=False)
ax3.scatter(box_data.index, box_data.values, marker='*', cmap='viridis',
s=300*box_data.apply(lambda x: (x % 7) + 1), c=box_data.apply(lambda x: (x % 5) + 1), alpha=0.6)
box_data.plot.box(whis=5.5, ax=ax4, showmeans=True, meanline=True, notch=True, sym='*', bootstrap=10000)
# Pie Data
ax1.set_title('customer has friends\n (which have used login via App)')
ax1.set_ylabel('')
# Hist
ax2.set_title('Friends per Customer')
ax2.set_xlabel("Number of Friends")
ax2.set_ylabel("Number of Customers")
ax2.yaxis.set_major_formatter(scalar_formatter) #fancy formatting
# Boxplot
ax4.xaxis.set_ticklabels('')
f.suptitle("Facebook Friends Analysis", fontsize=22)
# BG white
ax2.set_facecolor('white')
ax3.set_facecolor('white')
ax4.set_facecolor('white')
# Special Axis Stuff
ax1.axis("equal")
ax3.axis("off")
ax4.yaxis.tick_right() # axis to the right side
ax2.grid(True, which='major', color='lightgrey')
ax4.grid(True, which='major', color='lightgrey')
gs.tight_layout(f, rect=(0,0,1,0.95))
In [74]:
with plt.xkcd():
hist_data = pd.DataFrame(np.random.exponential(3.3, size=10000), columns=['data']).astype(int)
hist_data = hist_data['data'].value_counts()
pie_data = pd.Series(np.repeat(hist_data.index == 0, hist_data.values)).value_counts()
box_data = hist_data.copy()
digit_data = box_data.apply(lambda x: len(str(x)))
hist_data = pd.DataFrame(hist_data)
hist_data.loc[0, 'data2'] = hist_data.loc[0, 'data']
hist_data.loc[0, 'data'] = np.nan
from matplotlib.ticker import ScalarFormatter
scalar_formatter = ScalarFormatter(useMathText=True)
scalar_formatter.set_powerlimits((3,3))
gs = plt.GridSpec(2, 3, width_ratios=(1, 5, 1), height_ratios=(5,2))
f = plt.figure(figsize=(20,10))
ax1 = f.add_subplot(gs[0, 0])
ax2 = f.add_subplot(gs[0, 1:])
pie_data.plot.pie(ax=ax1,
labels=('Yea', 'Nay'), explode=(0,0.2), shadow=True,autopct='%1.1f%%', startangle=90)
hist_data.plot.bar(ax=ax2,
rot=0, legend=False)
# Pie Data
ax1.set_title('customer has friends\n (which have used login via App)')
ax1.set_ylabel('')
# Hist
ax2.set_title('Friends per Customer')
ax2.set_xlabel("Number of Friends")
ax2.set_ylabel("Number of Customers")
ax2.yaxis.set_major_formatter(scalar_formatter) #fancy formatting
# Boxplot
f.suptitle("Facebook Friends Analysis", fontsize=22)
# BG white
ax2.set_facecolor('white')
ax3.set_facecolor('white')
# Special Axis Stuff
ax1.axis("equal")
ax3.axis("off")
ax2.grid(True, which='major', color='lightgrey')
gs.tight_layout(f, rect=(0,0,1,0.95))
How did they achieve that? Basically not much code:
def squiggle_xy(a, b, c, d, i=np.arange(0.0, 2*np.pi, 0.05)):
return np.sin(i*a)*np.cos(i*b), np.sin(i*c)*np.cos(i*d)
fig = plt.figure(figsize=(8, 8))
# gridspec inside gridspec
outer_grid = gridspec.GridSpec(4, 4, wspace=0.0, hspace=0.0)
for i in range(16):
inner_grid = gridspec.GridSpecFromSubplotSpec(3, 3,
subplot_spec=outer_grid[i], wspace=0.0, hspace=0.0)
a, b = int(i/4)+1,i%4+1
for j, (c, d) in enumerate(product(range(1, 4), repeat=2)):
ax = plt.Subplot(fig, inner_grid[j])
ax.plot(*squiggle_xy(a, b, c, d))
ax.set_xticks([])
ax.set_yticks([])
fig.add_subplot(ax)
all_axes = fig.get_axes()
#show only the outside spines
for ax in all_axes:
for sp in ax.spines.values():
sp.set_visible(False)
if ax.is_first_row():
ax.spines['top'].set_visible(True)
if ax.is_last_row():
ax.spines['bottom'].set_visible(True)
if ax.is_first_col():
ax.spines['left'].set_visible(True)
if ax.is_last_col():
ax.spines['right'].set_visible(True)
plt.show()
In [ ]: