From fac00f181263bea575111c385fa575cf11ac31d1 Mon Sep 17 00:00:00 2001 From: Tianhua Liao Date: Wed, 26 Sep 2018 03:23:39 +0800 Subject: [PATCH] fix wrong dendrogram leaves determination bug (#1186) * fix wrong leaves determination bug * add test_dendrogram_ticklabels and comments about why/how to fix the dendrogram bugs. --- plotly/figure_factory/_dendrogram.py | 14 +++++++++++++- .../test_figure_factory/test_figure_factory.py | 9 +++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/plotly/figure_factory/_dendrogram.py b/plotly/figure_factory/_dendrogram.py index 72fc36c7d36..a59d33099d0 100644 --- a/plotly/figure_factory/_dendrogram.py +++ b/plotly/figure_factory/_dendrogram.py @@ -141,8 +141,20 @@ def __init__(self, X, orientation='bottom', labels=None, colorscale=None, if yvals_flat[i] == 0.0 and xvals_flat[i] not in self.zero_vals: self.zero_vals.append(xvals_flat[i]) - self.zero_vals.sort() + if len(self.zero_vals) > len(yvals) + 1: + # If the length of zero_vals is larger than the length of yvals, + # it means that there are wrong vals because of the identicial samples. + # Three and more identicial samples will make the yvals of spliting center into 0 and it will \ + # accidentally take it as leaves. + l_border = int(min(self.zero_vals)) + r_border = int(max(self.zero_vals)) + correct_leaves_pos = range(l_border, + r_border + 1, + int((r_border - l_border) / len(yvals))) + # Regenerating the leaves pos from the self.zero_vals with equally intervals. + self.zero_vals = [v for v in correct_leaves_pos] + self.zero_vals.sort() self.layout = self.set_figure_layout(width, height) self.data = dd_traces diff --git a/plotly/tests/test_optional/test_figure_factory/test_figure_factory.py b/plotly/tests/test_optional/test_figure_factory/test_figure_factory.py index 32c25113859..fb4ad1e4604 100644 --- a/plotly/tests/test_optional/test_figure_factory/test_figure_factory.py +++ b/plotly/tests/test_optional/test_figure_factory/test_figure_factory.py @@ -777,6 +777,15 @@ def test_dendrogram_colorscale(self): self.assert_fig_equal(dendro['data'][1], expected_dendro['data'][1]) self.assert_fig_equal(dendro['data'][2], expected_dendro['data'][2]) + def test_dendrogram_ticklabels(self): + X = np.array([[1, 2, 3, 4], [1, 2, 3, 4], [1, 3, 5, 6], [1, 4, 2, 3]]) + dendro = ff.create_dendrogram(X=X) + + expected_ticktext = ['2', '3', '0', '1'] + expected_tickvals = [5, 15, 25, 35] + + self.assertEqual(len(dendro.layout.xaxis.ticktext), 4) + self.assertEqual(len(dendro.layout.xaxis.tickvals), 4) class TestTrisurf(NumpyTestUtilsMixin, TestCase):