Skip to content

Commit 4ab398f

Browse files
committed
Allow the use of custom linkage/distance function in dendrograms.
[Scipy hierarchy](http://docs.scipy.org/doc/scipy-0.14.0/reference/cluster.hierarchy.html) allows multiple linkage modes for creating dendrograms. So far it has not been possible to create dendrograms using plotly with a different linkage mode than 'complete'. This commit allows the user to specify arbitrary linkage and distance function which can come either from the scipy package or user-created functions.
1 parent e8dc76e commit 4ab398f

File tree

1 file changed

+15
-7
lines changed

1 file changed

+15
-7
lines changed

plotly/tools.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6051,14 +6051,18 @@ def create_distplot(hist_data, group_labels,
60516051

60526052
@staticmethod
60536053
def create_dendrogram(X, orientation="bottom", labels=None,
6054-
colorscale=None):
6054+
colorscale=None, distfun=scs.distance.pdist,
6055+
linkagefun=lambda x: sch.linkage(x, 'complete')):
60556056
"""
60566057
BETA function that returns a dendrogram Plotly figure object.
60576058
60586059
:param (ndarray) X: Matrix of observations as array of arrays
60596060
:param (str) orientation: 'top', 'right', 'bottom', or 'left'
60606061
:param (list) labels: List of axis category labels(observation labels)
60616062
:param (list) colorscale: Optional colorscale for dendrogram tree
6063+
:param (function) distfun: Function to compute the pairwise distance from the observations
6064+
:param (function) linkagefun: Funktion to compute the linkage matrix from the pairwise distances
6065+
60626066
clusters
60636067
60646068
Example 1: Simple bottom oriented dendrogram
@@ -6114,7 +6118,8 @@ def create_dendrogram(X, orientation="bottom", labels=None,
61146118
if len(s) != 2:
61156119
exceptions.PlotlyError("X should be 2-dimensional array.")
61166120

6117-
dendrogram = _Dendrogram(X, orientation, labels, colorscale)
6121+
dendrogram = _Dendrogram(X, orientation, labels, colorscale,
6122+
distfun=distfun, linkagefun=linkagefun)
61186123

61196124
return {'layout': dendrogram.layout,
61206125
'data': dendrogram.data}
@@ -7041,7 +7046,8 @@ class _Dendrogram(FigureFactory):
70417046
"""Refer to FigureFactory.create_dendrogram() for docstring."""
70427047

70437048
def __init__(self, X, orientation='bottom', labels=None, colorscale=None,
7044-
width="100%", height="100%", xaxis='xaxis', yaxis='yaxis'):
7049+
width="100%", height="100%", xaxis='xaxis', yaxis='yaxis',
7050+
distfun=scs.distance.pdist, linkagefun=lambda x: sch.linkage(x, 'complete')):
70457051
# TODO: protected until #282
70467052
from plotly.graph_objs import graph_objs
70477053
self.orientation = orientation
@@ -7064,7 +7070,7 @@ def __init__(self, X, orientation='bottom', labels=None, colorscale=None,
70647070
self.sign[self.yaxis] = -1
70657071

70667072
(dd_traces, xvals, yvals,
7067-
ordered_labels, leaves) = self.get_dendrogram_traces(X, colorscale)
7073+
ordered_labels, leaves) = self.get_dendrogram_traces(X, colorscale, distfun, linkagefun)
70687074

70697075
self.labels = ordered_labels
70707076
self.leaves = leaves
@@ -7173,12 +7179,14 @@ def set_figure_layout(self, width, height):
71737179

71747180
return self.layout
71757181

7176-
def get_dendrogram_traces(self, X, colorscale):
7182+
def get_dendrogram_traces(self, X, colorscale, distfun, linkagefun):
71777183
"""
71787184
Calculates all the elements needed for plotting a dendrogram.
71797185
71807186
:param (ndarray) X: Matrix of observations as array of arrays
71817187
:param (list) colorscale: Color scale for dendrogram tree clusters
7188+
:param (function) distfun: Function to compute the pairwise distance from the observations
7189+
:param (function) linkagefun: Funktion to compute the linkage matrix from the pairwise distances
71827190
:rtype (tuple): Contains all the traces in the following order:
71837191
(a) trace_list: List of Plotly trace objects for dendrogram tree
71847192
(b) icoord: All X points of the dendrogram tree as array of arrays
@@ -7192,8 +7200,8 @@ def get_dendrogram_traces(self, X, colorscale):
71927200
"""
71937201
# TODO: protected until #282
71947202
from plotly.graph_objs import graph_objs
7195-
d = scs.distance.pdist(X)
7196-
Z = sch.linkage(d, method='complete')
7203+
d = distfun(X)
7204+
Z = linkagefun(d)
71977205
P = sch.dendrogram(Z, orientation=self.orientation,
71987206
labels=self.labels, no_plot=True)
71997207

0 commit comments

Comments
 (0)