*Note: Some of the visualisations will not work unless your browswer supports WebGL (i.e. not the firefox installed in the CVL). If you need to switch browsers, copy/paste the "localhost+token" link from the terminal you launched Jupyter notebook from*
PS: Many pieces of this notebook have been scavenged from other visualization notebooks and galleries. But the main things are from Tal Yarkoni's visualization-in-python notebook.
In this notebook, we will cover the following python packages. Some of them are exclusively for visualization while others like Pandas
have many other purposes:
The visualization of the first three is all based on matplotlib and use static images. While the last three create HTML outputs and allow much more interactive plots. We will talk about each one as we go along.
Check out the very helpful and cool new homepage https://python-graph-gallery.com/ to see how you can create different kinds of graphs.
As with most things in Python, we first load the relevant packages. Here we load three important packages:
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
The first line in the cell above is specific to Jupyter notebooks. It tells the interpreter to capture figures and embed them in the browser. Otherwise, they would end up almost in digital ether.
For example purposes, we will make use of a phenotypic dataset from the ABIDE II consortium. This multi-site dataset contains data from individuals diagnosed with Autism Spectrum Disorder (ASD) and healthy controls. We will first load the data from a single site.
Let's read this from the Web using Pandas. We explicitly specify that missing values are noted in the dataset as 'n/a'
.
df = pd.read_table('data/participants.tsv', na_values=['n/a'])
In the following cell we remove all columns that have missing values.
sub_df = df.dropna(axis=1)
sub_df.head()
site_id | participant_id | dx_group | age_at_scan | sex | handedness_category | handedness_scores | viq | piq | viq_test_type | piq_test_type | nonasd_psydx_icd9code | nonasd_psydx_label | eye_status_at_scan | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | ABIDEII-KKI_1 | 29273 | 1 | 8.476712 | 1 | 1.0 | 82.0 | 142.0 | 104.0 | WISC-IV | WISC-IV | 314.01 | ADHD combined | 1.0 |
1 | ABIDEII-KKI_1 | 29274 | 1 | 9.246575 | 1 | 1.0 | 83.0 | 104.0 | 79.0 | WISC-IV | WISC-IV | 296.3 | MDD (past) | 1.0 |
2 | ABIDEII-KKI_1 | 29275 | 1 | 8.646575 | 1 | 1.0 | 100.0 | 130.0 | 121.0 | WISC-IV | WISC-IV | 313.81 | ODD | 1.0 |
3 | ABIDEII-KKI_1 | 29276 | 1 | 9.216438 | 2 | 1.0 | 100.0 | 128.0 | 115.0 | WISC-IV | WISC-IV | 314.01; 300.29 | ADHD combined; simple phobia | 1.0 |
4 | ABIDEII-KKI_1 | 29277 | 1 | 12.789041 | 1 | 1.0 | 90.0 | 132.0 | 123.0 | WISC-IV | WISC-IV | 314.01 | ADHD hyperactive/impulsive | 1.0 |
Using the keys
method we can look at all the column headings that are left.
list(sub_df.keys())
['site_id', 'participant_id', 'dx_group', 'age_at_scan ', 'sex', 'handedness_category', 'handedness_scores', 'viq', 'piq', 'viq_test_type', 'piq_test_type', 'nonasd_psydx_icd9code', 'nonasd_psydx_label', 'eye_status_at_scan']
Lets now see how we can visualize the information in this dataset (sub_df
). Python has quite a lot of visualization packages. Undeniably, the most famous and at the same time versatile, that additionally is the basis of most others, is matplotlib.
matplotlib
¶plt.figure(figsize=(10, 5))
plt.scatter(sub_df['age_at_scan '], sub_df.viq)
plt.xlabel('Age at scan')
plt.ylabel('Verbal IQ')
plt.title('Comparing Age and Verbal IQ');
Thinking about how plotting works with matplotlib
, we can explore a different approach to plotting, where we at first generate our figure and access certain parts of it, in order to modify them:
# Set up a figure with 3 columns
fig, axes = plt.subplots(1, 3, figsize=(15, 4))
# Scatter plot in top left
axes[0].scatter(sub_df['age_at_scan '], sub_df['viq'])
axes[0].axis('off')
# Mean species petal widths in top right
means = sub_df.groupby('dx_group')['viq'].mean()
axes[1].bar(np.arange(len(means))+1, means)
# Note how **broken** this is without additional code
axes[1].set_xticklabels(means.index)
# More scatter plots, breaking up by species
colors = ['blue', 'green', 'red']
for i, (s, grp) in enumerate(sub_df.groupby('dx_group')):
axes[2].scatter(grp['age_at_scan '], grp['viq'], c=colors[i])
Create a figure with a single axes and replot the scatterplot on the right to group by sex
instead of dx_group
.
red
and gray
# More scatter plots, breaking up by species
plt.figure(figsize=(10, 5))
colors = ['red', 'black']
for i, (s, grp) in enumerate(sub_df.groupby('sex')):
plt.scatter(grp['age_at_scan '], grp['viq'], c=colors[i], alpha=0.5)
plt.xlabel('Age at scan')
plt.xlabel('Verbal IQ')
plt.legend(['Male', 'Female']);
# Create solution here
You can reuse code directly from the matplotlib gallery.
# Adapted from https://matplotlib.org/gallery/statistics/histogram_multihist.html
import numpy as np
import matplotlib.pyplot as plt
n_bins = 10
x = np.random.randn(1000, 3)
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(10, 8))
ax0, ax1, ax2, ax3 = axes.flatten()
colors = ['red', 'tan', 'lime']
ax0.hist(x, n_bins, normed=1, histtype='bar', color=colors, label=colors)
ax0.legend(prop={'size': 10})
ax0.set_title('bars with legend')
ax1.hist(x, n_bins, normed=1, histtype='bar', stacked=True)
ax1.set_title('stacked bar')
ax2.hist(x, n_bins, histtype='step', stacked=True, fill=False)
ax2.set_title('stack step (unfilled)')
# Make a multiple-histogram of data-sets with different length.
x_multi = [np.random.randn(n) for n in [10000, 5000, 2000]]
ax3.hist(x_multi, n_bins, histtype='bar')
ax3.set_title('different sample sizes')
fig.tight_layout()
plt.show()
/opt/miniconda-latest/envs/neuro/lib/python3.6/site-packages/matplotlib/axes/_axes.py:6521: MatplotlibDeprecationWarning: The 'normed' kwarg was deprecated in Matplotlib 2.1 and will be removed in 3.1. Use 'density' instead. alternative="'density'", removal="3.1")
# Adapted from https://matplotlib.org/gallery/lines_bars_and_markers/cohere.html
import numpy as np
import matplotlib.pyplot as plt
dt = 0.01
t = np.arange(0, 30, dt)
nse1 = np.random.randn(len(t)) # white noise 1
nse2 = np.random.randn(len(t)) # white noise 2
# Two signals with a coherent part at 10Hz and a random part
s1 = np.sin(2 * np.pi * 10 * t) + nse1
s2 = np.sin(2 * np.pi * 10 * t) + nse2
fig, axs = plt.subplots(2, 1, figsize=(10, 5))
axs[0].plot(t, s1, t, s2)
axs[0].set_xlim(0, 2)
axs[0].set_xlabel('time')
axs[0].set_ylabel('s1 and s2')
axs[0].grid(True)
cxy, f = axs[1].cohere(s1, s2, 256, 1. / dt)
axs[1].set_ylabel('coherence')
fig.tight_layout()
plt.show()
# Adapted from http://matplotlib.org/examples/mplot3d/subplot3d_demo.html
from mpl_toolkits.mplot3d.axes3d import Axes3D
import matplotlib.pyplot as plt
# imports specific to the plots in this example
import numpy as np
from matplotlib import cm
from mpl_toolkits.mplot3d.axes3d import get_test_data
# Twice as wide as it is tall.
fig = plt.figure(figsize=(15, 5))
#---- First subplot
ax = fig.add_subplot(1, 2, 1, projection='3d')
X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)
surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm,
linewidth=0, antialiased=False)
ax.set_zlim3d(-1.01, 1.01)
fig.colorbar(surf, shrink=0.5, aspect=10)
#---- Second subplot
ax = fig.add_subplot(1, 2, 2, projection='3d')
X, Y, Z = get_test_data(0.05)
ax.plot_wireframe(X, Y, Z, rstride=10, cstride=10);
matplotlib
¶Pros
Cons
matplotlib
's powermatplotlib
(e.g., nilearn in neuroimaging)Pandas
¶import pandas as pd
iris = pd.read_csv('data/iris.csv')
iris[::8]
SepalLength | SepalWidth | PetalLength | PetalWidth | Species | |
---|---|---|---|---|---|
0 | 5.1 | 3.5 | 1.4 | 0.2 | setosa |
8 | 4.4 | 2.9 | 1.4 | 0.2 | setosa |
16 | 5.4 | 3.9 | 1.3 | 0.4 | setosa |
24 | 4.8 | 3.4 | 1.9 | 0.2 | setosa |
32 | 5.2 | 4.1 | 1.5 | 0.1 | setosa |
40 | 5.0 | 3.5 | 1.3 | 0.3 | setosa |
48 | 5.3 | 3.7 | 1.5 | 0.2 | setosa |
56 | 6.3 | 3.3 | 4.7 | 1.6 | versicolor |
64 | 5.6 | 2.9 | 3.6 | 1.3 | versicolor |
72 | 6.3 | 2.5 | 4.9 | 1.5 | versicolor |
80 | 5.5 | 2.4 | 3.8 | 1.1 | versicolor |
88 | 5.6 | 3.0 | 4.1 | 1.3 | versicolor |
96 | 5.7 | 2.9 | 4.2 | 1.3 | versicolor |
104 | 6.5 | 3.0 | 5.8 | 2.2 | virginica |
112 | 6.8 | 3.0 | 5.5 | 2.1 | virginica |
120 | 6.9 | 3.2 | 5.7 | 2.3 | virginica |
128 | 6.4 | 2.8 | 5.6 | 2.1 | virginica |
136 | 6.3 | 3.4 | 5.6 | 2.4 | virginica |
144 | 6.7 | 3.3 | 5.7 | 2.5 | virginica |
# KDE plot of all iris attributes, collapsing over species
iris.plot(kind='kde', figsize=(10, 5));
# Separate boxplot of iris attributes for each species
iris.groupby('Species').boxplot(rot=45, figsize=(10,6));
Seaborn
¶Seaborn abstracts away many of the complexities to deal with such minutiae and provides a high-level API for creating aesthetic plots.
For example, the following command auto adjusts the setting for the figure to reflect what you are using the figure for.
import seaborn as sns
# Adjust the context of the plot
sns.set_context('poster') # http://seaborn.pydata.org/tutorial/aesthetics.html#scaling-plot-elements
sns.set_palette('pastel') # http://seaborn.pydata.org/tutorial/color_palettes.html
# But still use matplotlib to do the plotting
plt.figure(figsize=(10, 5))
plt.scatter(sub_df['age_at_scan '], sub_df.viq)
plt.xlabel('Age at scan')
plt.ylabel('Verbal IQ')
plt.title('Comparing Age and Verbal IQ');
# Adjust the context of the plot
sns.set_context('paper')
sns.set_palette('colorblind')
# But still use matplotlib to do the plotting
plt.figure(figsize=(10, 5))
plt.scatter(sub_df['age_at_scan '], sub_df.viq)
plt.xlabel('Age at scan')
plt.ylabel('Verbal IQ')
plt.title('Comparing Age and Verbal IQ');
Now let's redo the scatter plot in seaborn style.
sns.jointplot(x='age_at_scan ', y='viq', data=sub_df, stat_func=None);
Seaborn
example¶Given the dataset we are using, what would you change to provide a better understanding of the data.
Information about:
should be encoded separately.
One way to do this with seaborn is to use a more general interface called the FacetGrid.
Let's replot the figure while learning about a few new commands. Try to understand what the function does and try to change some parameters.
sns.set(style="whitegrid", palette="pastel", color_codes=True)
sns.set_context('poster')
kws = dict(s=100, alpha=0.75, linewidth=0.15, edgecolor="k")
g = sns.FacetGrid(sub_df, col="sex", hue="dx_group", palette="Set1",
hue_order=[1, 2], size=5.5)
g = (g.map(plt.scatter, "age_at_scan ", "viq", **kws).add_legend())
/opt/miniconda-latest/envs/neuro/lib/python3.6/site-packages/seaborn/axisgrid.py:230: UserWarning: The `size` paramter has been renamed to `height`; please update your code. warnings.warn(msg, UserWarning)
With just a few lines of code, note how much control you have over the figure.
Using a pairwise plot, compare the distributions of age
, viq
, and piq
with respect to dx_group
.
ticks
paper
dx_group
variable from being on the plotsns.set_palette(palette='hls')
sns.set_context('paper')
sns.set_style('ticks')
sns.pairplot(df[['age_at_scan ', 'viq', 'piq', 'dx_group']],
vars=['age_at_scan ', 'viq', 'piq'], hue="dx_group", size=3);
/opt/miniconda-latest/envs/neuro/lib/python3.6/site-packages/seaborn/axisgrid.py:2065: UserWarning: The `size` parameter has been renamed to `height`; pleaes update your code. warnings.warn(msg, UserWarning)
# Create solution here
Using a violin plot separate out viq
as a function of sex
and dx_group
.
dx_group
should be on each half of each violinsex
categories.# Draw a nested violinplot and split the violins for easier comparison
sns.set(style="whitegrid", palette="pastel", color_codes=True,
rc={"figure.figsize": (8, 5)})
sns.set_context('poster')
sns.violinplot(x="sex", y="viq", hue="dx_group", data=sub_df, split=True,
inner="quart", palette={1: "b", 2: "y"})
sns.despine(left=True)
# Create solution here
You can reuse code directly from the seaborn gallery.
# Adapted from http://seaborn.pydata.org/examples/regression_marginals.html
import seaborn as sns
sns.set(style="darkgrid", color_codes=True)
tips = pd.read_csv('data/tips.csv')
g = sns.jointplot("total_bill", "tip", data=tips, kind="reg",
xlim=(0, 60), ylim=(0, 12), color="r", size=7)
/opt/miniconda-latest/envs/neuro/lib/python3.6/site-packages/seaborn/axisgrid.py:2262: UserWarning: The `size` paramter has been renamed to `height`; please update your code. warnings.warn(msg, UserWarning)
# Adapted from http://seaborn.pydata.org/examples/grouped_boxplot.html
import seaborn as sns
sns.set(style="ticks")
# Load the example tips dataset
tips = pd.read_csv('data/tips.csv')
print(tips.head())
# Draw a nested boxplot to show bills by day and sex
sns.boxplot(x="day", y="total_bill", hue="sex", data=tips, palette="PRGn")
sns.despine(offset=10, trim=True, )
total_bill tip sex smoker day time size 0 16.99 1.01 Female No Sun Dinner 2 1 10.34 1.66 Male No Sun Dinner 3 2 21.01 3.50 Male No Sun Dinner 3 3 23.68 3.31 Male No Sun Dinner 2 4 24.59 3.61 Female No Sun Dinner 4
# Adapted from http://seaborn.pydata.org/examples/distplot_options.html
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
sns.set(style="white", palette="muted", color_codes=True)
rs = np.random.RandomState(10)
# Set up the matplotlib figure
f, axes = plt.subplots(1, 4, figsize=(12, 3), sharex=True)
sns.despine(left=True)
# Generate a random univariate dataset
d = rs.normal(size=100)
# Plot a simple histogram with binsize determined automatically
sns.distplot(d, kde=False, color="b", ax=axes[0])
# Plot a kernel density estimate and rug plot
sns.distplot(d, hist=False, rug=True, color="r", ax=axes[1])
# Plot a filled kernel density estimate
sns.distplot(d, hist=False, color="g", kde_kws={"shade": True}, ax=axes[2])
# Plot a historgram and kernel density estimate
sns.distplot(d, color="m", ax=axes[3])
plt.setp(axes, yticks=[])
plt.tight_layout()
iris.head()
SepalLength | SepalWidth | PetalLength | PetalWidth | Species | |
---|---|---|---|---|---|
0 | 5.1 | 3.5 | 1.4 | 0.2 | setosa |
1 | 4.9 | 3.0 | 1.4 | 0.2 | setosa |
2 | 4.7 | 3.2 | 1.3 | 0.2 | setosa |
3 | 4.6 | 3.1 | 1.5 | 0.2 | setosa |
4 | 5.0 | 3.6 | 1.4 | 0.2 | setosa |
# Adapted from https://seaborn.pydata.org/tutorial/axis_grids.html
import seaborn as sns
sns.set(style="ticks")
iris = pd.read_csv('data/iris.csv')
g = sns.pairplot(iris, hue="Species", palette="Set2", kind='reg',
diag_kind="kde", size=2.5)
# Adapted from https://seaborn.pydata.org/tutorial/axis_grids.html
attend = pd.read_csv('data/attention.csv').query("subject <= 12")
g = sns.FacetGrid(attend, col="subject", col_wrap=4, size=2, ylim=(0, 10))
g.map(sns.pointplot, "solutions", "score", color=".3", ci=None);
/opt/miniconda-latest/envs/neuro/lib/python3.6/site-packages/seaborn/axisgrid.py:715: UserWarning: Using the pointplot function without specifying `order` is likely to produce an incorrect plot. warnings.warn(warning)
matplotlib
bokeh
, plotly
, HoloViews
...Bokeh
¶matplotlib
plots to Bokeh, but not vice versa# Adapted from http://bokeh.pydata.org/en/latest/docs/gallery/iris.html
from bokeh.plotting import figure, show, output_notebook
from bokeh.sampledata.iris import flowers
output_notebook()
colormap = {'setosa': 'red', 'versicolor': 'green', 'virginica': 'blue'}
colors = [colormap[x] for x in flowers['species']]
p = figure(title = "Iris Morphology")
p.xaxis.axis_label = 'Petal Length'
p.yaxis.axis_label = 'Petal Width'
p.circle(flowers["petal_length"], flowers["petal_width"],
color=colors, fill_alpha=0.2, size=10)
show(p)
import numpy as np
from bokeh.plotting import figure, show, output_notebook
from bokeh.models import HoverTool, ColumnDataSource
from bokeh.sampledata.les_mis import data
output_notebook()
nodes = data['nodes']
names = [node['name'] for node in sorted(data['nodes'], key=lambda x: x['group'])]
N = len(nodes)
counts = np.zeros((N, N))
for link in data['links']:
counts[link['source'], link['target']] = link['value']
counts[link['target'], link['source']] = link['value']
colormap = ["#444444", "#a6cee3", "#1f78b4", "#b2df8a", "#33a02c", "#fb9a99",
"#e31a1c", "#fdbf6f", "#ff7f00", "#cab2d6", "#6a3d9a"]
xname = []
yname = []
color = []
alpha = []
for i, node1 in enumerate(nodes):
for j, node2 in enumerate(nodes):
xname.append(node1['name'])
yname.append(node2['name'])
alpha.append(min(counts[i,j]/4.0, 0.9) + 0.1)
if node1['group'] == node2['group']:
color.append(colormap[node1['group']])
else:
color.append('lightgrey')
source = ColumnDataSource(data=dict(xname=xname, yname=yname, colors=color,
alphas=alpha, count=counts.flatten()))
p = figure(title="Les Mis Occurrences",
x_axis_location="above", tools="hover,save",
x_range=list(reversed(names)), y_range=names)
p.plot_width = 800
p.plot_height = 800
p.grid.grid_line_color = None
p.axis.axis_line_color = None
p.axis.major_tick_line_color = None
p.axis.major_label_text_font_size = "5pt"
p.axis.major_label_standoff = 0
p.xaxis.major_label_orientation = np.pi/3
p.rect('xname', 'yname', 0.9, 0.9, source=source,
color='colors', alpha='alphas', line_color=None,
hover_line_color='black', hover_color='colors')
p.select_one(HoverTool).tooltips = [('names', '@yname, @xname'),
('count', '@count')]
show(p) # show the plot
# Adapted from https://plot.ly/python/ipython-notebook-tutorial/
import plotly
plotly.offline.init_notebook_mode()
import plotly.figure_factory as ff
from plotly.graph_objs import *
import pandas as pd
df = pd.read_csv('data/school_earnings.csv')
table = ff.create_table(df)
trace_women = Bar(x=df.School, y=df.Women, name='Women', marker=dict(color='#ffcdd2'))
trace_men = Bar(x=df.School, y=df.Men, name='Men', marker=dict(color='#A2D5F2'))
trace_gap = Bar(x=df.School, y=df.Gap, name='Gap', marker=dict(color='#59606D'))
data = [trace_women, trace_men, trace_gap]
layout = Layout(title="Average Earnings for Graduates",
xaxis=dict(title='School'),
yaxis=dict(title='Salary (in thousands)'))
fig = Figure(data=data, layout=layout)
plotly.offline.iplot(fig)
# Adapted from https://plot.ly/python/line-and-scatter/
import plotly
plotly.offline.init_notebook_mode()
import plotly.graph_objs as go
# Create random data with numpy
import numpy as np
N = 100
random_x = np.linspace(0, 1, N)
random_y0 = np.random.randn(N) + 5
random_y1 = np.random.randn(N)
random_y2 = np.random.randn(N) - 5
# Create traces
trace0 = go.Scatter(x=random_x, y=random_y0, mode='lines', name='lines')
trace1 = go.Scatter(x=random_x, y=random_y1, mode='lines+markers', name='lines+markers')
trace2 = go.Scatter(x=random_x, y=random_y2, mode='markers', name='markers')
data = [trace0, trace1, trace2]
plotly.offline.iplot(data, filename='line-mode')
# Adapted from https://plot.ly/python/continuous-error-bars/
import plotly
plotly.offline.init_notebook_mode()
import plotly.graph_objs as go
import pandas as pd
df = pd.read_csv('data/wind_speed_laurel_nebraska.csv')
upper_bound = go.Scatter(
name='Upper Bound', x=df['Time'], y=df['10 Min Sampled Avg'] + df['10 Min Std Dev'], mode='lines',
marker=dict(color="#444444"), line=dict(width=0), fillcolor='rgba(68, 68, 68, 0.3)', fill='tonexty')
trace = go.Scatter(
name='Measurement', x=df['Time'], y=df['10 Min Sampled Avg'], mode='lines',
line=dict(color='rgb(31, 119, 180)'), fillcolor='rgba(68, 68, 68, 0.3)', fill='tonexty')
lower_bound = go.Scatter(
name='Lower Bound', x=df['Time'], y=df['10 Min Sampled Avg']-df['10 Min Std Dev'],
marker=dict(color="#444444"), line=dict(width=0), mode='lines')
# Trace order can be important with continuous error bars
data = [lower_bound, trace, upper_bound]
layout = go.Layout(yaxis=dict(title='Wind speed (m/s)'),
title='Continuous, variable value error bars.', showlegend = False)
fig = go.Figure(data=data, layout=layout)
plotly.offline.iplot(fig, filename='pandas-continuous-error-bars')
# Adapted from https://plot.ly/python/3d-surface-plots/
import plotly
plotly.offline.init_notebook_mode()
import plotly.graph_objs as go
import pandas as pd
# Read data from a csv
z_data = pd.read_csv('data/mt_bruno_elevation.csv')
data = [go.Surface(z=z_data.as_matrix())]
layout = go.Layout(autosize=True, width=500, height=500, margin=dict(l=65, r=50, b=65, t=90))
fig = go.Figure(data=data, layout=layout)
plotly.offline.iplot(fig)
/opt/miniconda-latest/envs/neuro/lib/python3.6/site-packages/ipykernel_launcher.py:11: FutureWarning: Method .as_matrix will be removed in a future version. Use .values instead.
# Adapted from http://holoviews.org/gallery/demos/bokeh/iris_splom_example.html#bokeh-gallery-iris-splom-example
import numpy as np
import holoviews as hv
hv.extension('bokeh')
# Declaring data
from bokeh.sampledata.iris import flowers
from holoviews.operation import gridmatrix
ds = hv.Dataset(flowers)
grouped_by_species = ds.groupby('species', container_type=hv.NdOverlay)
grid = gridmatrix(grouped_by_species, diagonal_type=hv.Scatter)
# Plot
plot_opts = dict(tools=['hover', 'box_select'], bgcolor='#efe8e2')
style = dict(fill_alpha=0.2, size=4)
grid({'Scatter': {'plot': plot_opts, 'style': style}})
WARNING:param.GridMatrix01410: Use of __call__ to set options will be deprecated in future. Use the equivalent opts method or use the recommended .options method instead.
# Adapted from http://holoviews.org/gallery/demos/bokeh/mandelbrot_section.html#bokeh-gallery-mandelbrot-section
import numpy as np
import holoviews as hv
hv.extension('bokeh')
# Load the data
import io
try: from urllib2 import urlopen
except: from urllib.request import urlopen
raw = np.load('data/mandelbrot.npy')
array = np.load(io.BytesIO(raw)).astype(np.float32)[::4,::4]
%%opts Points [scaling_factor=50] Contours [show_legend=False] (color='w')
dots = np.linspace(-0.45, 0.45, 19)
fractal = hv.Image(array)
# First example on the old holoviews.org homepage was:
# ((fractal * hv.HLine(y=0)).hist() + fractal.sample(y=0))
layouts = {y: (fractal * hv.Points(fractal.sample([(i,y) for i in dots])) +
fractal.sample(y=y) +
hv.operation.threshold(fractal, level=np.percentile(fractal.sample(y=y)['z'], 90)) +
hv.operation.contours(fractal, levels=[np.percentile(fractal.sample(y=y)['z'], 60)]))
for y in np.linspace(-0.4, 0.4, 10)} # Half the frames of the bokeh version
hv.HoloMap(layouts, kdims='Y').collate().cols(2)
# Adapted from http://holoviews.org/gallery/demos/bokeh/measles_example.html#bokeh-gallery-measles-example
import numpy as np
import holoviews as hv
import pandas as pd
hv.extension('bokeh')
# Declaring data
data = pd.read_csv('data/measles_incidence.csv', skiprows=2, na_values='-')
yearly_data = data.drop('WEEK', axis=1).groupby('YEAR').sum().reset_index()
measles = pd.melt(yearly_data, id_vars=['YEAR'], var_name='State', value_name='Incidence')
heatmap = hv.HeatMap(measles, label='Measles Incidence')
aggregate = hv.Dataset(heatmap).aggregate('YEAR', np.mean, np.std)
vline = hv.VLine(1963)
marker = hv.Text(1964, 800, 'Vaccine introduction', halign='left')
agg = hv.ErrorBars(aggregate) * hv.Curve(aggregate)
# Plot
hm_opts = dict(width=900, height=500, tools=['hover'], logz=True, invert_yaxis=True,
xrotation=90, labelled=[], toolbar='above', xaxis=None)
overlay_opts = dict(width=900, height=200, show_title=False)
vline_opts = dict(line_color='black')
opts = {'HeatMap': {'plot': hm_opts}, 'Overlay': {'plot': overlay_opts}, 'VLine': {'style': vline_opts}}
(heatmap + agg * vline * marker).opts(opts).cols(1)