Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 814c1d5

Browse files
committed
Merge pull request plotly#312 from plotly/dendrogram-andrew-tweaks
Dendrogram andrew tweaks
2 parents 390c09d + 3815a8f commit 814c1d5

File tree

6 files changed

+652
-6
lines changed

6 files changed

+652
-6
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,15 @@ This project adheres to [Semantic Versioning](http://semver.org/).
44

55
## [Unreleased]
66

7+
## [1.8.7] - 2015-10-01
8+
### Added
9+
- The FigureFactory can now create dendrogram plots with `.create_dendrogram`.
10+
711
## [1.8.6] - 2015-09-28
12+
### Fixed
813
- Saving "world_readable" to your config file via `plotly.tools.set_config` actually works.
14+
15+
### Added
916
- You can also save `auto_open` and `sharing` to the config file so that you can forget these
1017
keyword argument in `py.iplot` and `py.plot`.
1118

plotly/tests/test_core/test_tools/test_figure_factory.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
import datetime
55
from nose.tools import raises
6-
76
import plotly.tools as tls
87
from plotly.exceptions import PlotlyError
98
from plotly.graph_objs import graph_objs

plotly/tests/test_optional/optional_utils.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,93 @@
33
import matplotlib
44
# Force matplotlib to not use any Xwindows backend.
55
matplotlib.use('Agg')
6+
7+
import numpy as np
8+
69
from plotly.matplotlylib import Exporter, PlotlyRenderer
10+
from plotly.tests.utils import is_num_list
11+
from plotly.utils import get_by_path, node_generator
712

813

914
def run_fig(fig):
1015
renderer = PlotlyRenderer()
1116
exporter = Exporter(renderer)
1217
exporter.run(fig)
1318
return renderer
19+
20+
21+
class NumpyTestUtilsMixin(object):
22+
"""Provides some helper functions to make testing easier."""
23+
24+
def _format_path(self, path):
25+
str_path = [repr(p) for p in path]
26+
return '[' + ']['.join(sp for sp in str_path) + ']'
27+
28+
def assert_dict_equal(self, d1, d2, msg=None):
29+
"""
30+
Uses `np.allclose()` on number arrays.
31+
32+
:raises: (AssertionError) Using TestCase's self.failureException
33+
34+
"""
35+
self.assertIsInstance(d1, dict, 'First argument is not a dictionary')
36+
self.assertIsInstance(d2, dict, 'Second argument is not a dictionary')
37+
38+
for node, path in node_generator(d1):
39+
40+
# first check that this sub-dict is contained in both dicts
41+
try:
42+
comp_node = get_by_path(d2, path)
43+
except (KeyError, IndexError):
44+
standard_msg = (
45+
'Path {} exists in dict 1, but not dict 2.'
46+
.format(path)
47+
)
48+
self.fail(self._formatMessage(msg, standard_msg))
49+
self.assertIsInstance(
50+
comp_node, dict, 'Value at path {} is not a dict.'.format(path)
51+
)
52+
53+
# check that each key in the first is contained in the second
54+
for key, val in node.items():
55+
if isinstance(val, dict):
56+
continue # this gets tested as its own node
57+
58+
# check that the values at this key are equal
59+
val_path = path + (key, )
60+
try:
61+
comp_val = comp_node[key]
62+
except KeyError:
63+
standard_msg = (
64+
'Path {} exists in dict 1, but not dict 2.'
65+
.format(self._format_path(val_path))
66+
)
67+
self.fail(self._formatMessage(msg, standard_msg))
68+
69+
if (isinstance(val, np.ndarray) or
70+
isinstance(comp_val, np.ndarray)):
71+
if np.array_equal(val, comp_val):
72+
continue
73+
elif val == comp_val:
74+
continue
75+
76+
if is_num_list(val) and is_num_list(comp_val):
77+
if np.allclose(val, comp_val):
78+
continue
79+
80+
standard_msg = (
81+
'Value comparison failed at path {}.\n'
82+
'{} != {}'
83+
.format(self._format_path(val_path), val, comp_val)
84+
)
85+
self.fail(self._formatMessage(msg, standard_msg))
86+
87+
# finally, check that keys in the second are in the first
88+
for key in comp_node:
89+
val_path = path + (key, )
90+
if key not in node:
91+
standard_msg = (
92+
'Path {} exists in dict 2, but not dict 1.'
93+
.format(self._format_path(val_path))
94+
)
95+
self.fail(self._formatMessage(msg, standard_msg))

0 commit comments

Comments
 (0)