Skip to content

Commit b9352d7

Browse files
committed
Merge branch 'master' into dendrogram-andrew-tweaks
Conflicts: plotly/tools.py
2 parents 88842b1 + ff2dc96 commit b9352d7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+18003
-7011
lines changed

.gitmodules

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
[submodule "submodules/mplexporter"]
22
path = submodules/mplexporter
33
url = git://github.com/mpld3/mplexporter.git
4-
[submodule "submodules/graph_reference"]
5-
path = submodules/graph_reference
6-
url = git://github.com/plotly/graph_reference.git
74
[submodule "submodules/chunked_requests"]
85
path = submodules/chunked_requests
96
url = git://github.com/chriddyp/chunked_requests.git

CHANGELOG.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Change Log
2+
All notable changes to this project will be documented in this file.
3+
This project adheres to [Semantic Versioning](http://semver.org/).
4+
5+
## [Unreleased]
6+
7+
## [1.8.3] - 2015-08-14
8+
### Fixed
9+
- Fixed typos in `plot` and `iplot` documentations
10+
11+
## [1.8.2] - 2015-08-11
12+
### Added
13+
- CHANGELOG
14+
- `sharing` keyword argument for `plotly.plotly.plot` and `plotly.plotly.iplot` with options `'public' | 'private' | 'secret'` to control the privacy of the charts. Depreciates `world_readable`
15+
16+
### Changed
17+
- If the response from `plot` or `iplot` contains an error message, raise an exception
18+
19+
### Removed
20+
- `height` and `width` are no longer accepted in `iplot`. Just stick them into your figure's layout instead, it'll be more consistent when you view it outside of the IPython notebook environment. So, instead of this:
21+
22+
```
23+
py.iplot([{'x': [1, 2, 3], 'y': [3, 1, 5]}], height=800)
24+
```
25+
26+
do this:
27+
28+
```
29+
py.iplot({
30+
'data': [{'x': [1, 2, 3], 'y': [3, 1, 5]}],
31+
'layout': {'height': 800}
32+
})
33+
```
34+
35+
### Fixed
36+
- The height of the graph in `iplot` respects the figure's height in layout

make_instructions.txt

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ Available targets (i.e. $ make target):
1818

1919
readme -> `less` this file
2020

21+
update_default_schema -> download the latest plot schema from plot.ly
22+
2123
setup_subs -> delete old submodule locations, init, update, and sync new
2224

2325
install -> 1. sync submodules 2. install plotly with setup.py
@@ -28,16 +30,12 @@ Available targets (i.e. $ make target):
2830

2931
sync_chunked -> sync chunked_requests submodule ONLY
3032

31-
sync_refs -> sync graph_reference submodule ONLY
32-
3333
pull_subs -> `cd` into *each* submodule and `git pull origin master`
3434

3535
pull_mpl -> pull in mplexporter *master* branch
3636

3737
pull_chunked -> pull in chunked_requests *master* branch
3838

39-
pull_refs -> pull in graph_reference *master* branch
40-
4139
################################################################################
4240

4341
Getting setup:
@@ -49,8 +47,8 @@ Getting setup:
4947

5048
Pulling in changes from subprojects:
5149

52-
1. Only pull submodules that you require (e.g., $ make pull_refs)
53-
2. Make sure to sync these changes (e.g., $ make sync_refs)
50+
1. Only pull submodules that you require (e.g., $ make pull_mpl)
51+
2. Make sure to sync these changes (e.g., $ make sync_mpl)
5452

5553
################################################################################
5654

makefile

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ readme :
66

77
setup_subs :
88
@echo "Deleting old submodule locations, if they exist"
9-
rm -rf plotly/graph_reference
109
rm -rf plotly/mplexporter
1110
rm -rf plotly/chunked_requests
1211
rm -rf plotly/plotly/chunked_requests
@@ -17,16 +16,25 @@ setup_subs :
1716
git submodule update
1817
make sync_subs
1918

19+
update_default_schema :
20+
@echo "Making sure the default-schema.json file is up to date"
21+
python -c "import json;\
22+
from plotly.graph_reference import GRAPH_REFERENCE;\
23+
f = open('plotly/graph_reference/default-schema.json', 'w');\
24+
json.dump(GRAPH_REFERENCE, f, indent=4, sort_keys=True,\
25+
separators=(',', ': '));\
26+
f.close()"
27+
2028
install : sync_subs
2129
@echo ""
2230
@echo "Installing Python API with make"
2331
python setup.py install
2432

25-
sync_subs : sync_mpl sync_chunked sync_refs
33+
sync_subs : sync_mpl sync_chunked
2634
@echo ""
2735
@echo "Submodules synced"
2836

29-
pull_subs : pull_mpl pull_chunked pull_refs
37+
pull_subs : pull_mpl pull_chunked
3038
@echo ""
3139
@echo "Submodules pulled"
3240

@@ -40,21 +48,6 @@ sync_chunked : submodules/chunked_requests
4048
@echo "Syncing chunked_requests directories"
4149
rsync -r submodules/chunked_requests/chunked_requests plotly/plotly/
4250

43-
sync_refs : submodules/graph_reference
44-
@echo ""
45-
@echo "Syncing graph_reference directories"
46-
rm -rf plotly/graph_reference
47-
mkdir plotly/graph_reference
48-
cp submodules/graph_reference/graph_objs/python/graph_objs_meta.json plotly/graph_reference
49-
cp submodules/graph_reference/graph_objs/python/KEY_TO_NAME.json plotly/graph_reference
50-
cp submodules/graph_reference/graph_objs/python/NAME_TO_KEY.json plotly/graph_reference
51-
cp submodules/graph_reference/graph_objs/python/OBJ_MAP.json plotly/graph_reference
52-
53-
pull_refs : submodules/graph_reference
54-
@echo ""
55-
@echo "Pulling down updates from graph_reference"
56-
cd submodules/graph_reference; git pull origin master
57-
5851
pull_mpl : submodules/mplexporter
5952
@echo ""
6053
@echo "Pulling down updates from mplexporter"

optional-requirements.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,6 @@ ipython[all]
1919

2020
## pandas deps for some matplotlib functionality ##
2121
pandas
22+
23+
## scipy deps for some FigureFactory functions ##
24+
scipy

plotly/exceptions.py

Lines changed: 61 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,6 @@
44
55
A module that contains plotly's exception hierarchy.
66
7-
message (required!) (should be root message + caller message)
8-
info: (required!)
9-
path_to_error (required!)
10-
minimal_message (required!)
11-
12-
- minimal_message is set inside this module, should not be set elsewhere
13-
14-
- message is set inside this module, should not be set elsewhere
15-
16-
177
"""
188
import json
199

@@ -56,7 +46,7 @@ def __str__(self):
5646
return self.message
5747

5848

59-
# Grid Errors #
49+
# Grid Errors
6050
COLUMN_NOT_YET_UPLOADED_MESSAGE = (
6151
"Hm... it looks like your column '{column_name}' hasn't "
6252
"been uploaded to Plotly yet. You need to upload your "
@@ -72,126 +62,86 @@ def __str__(self):
7262
"the column \"{0}\" and try again."
7363
)
7464

75-
# Would Cause Server Errors
7665

7766
class PlotlyEmptyDataError(PlotlyError):
7867
pass
7968

8069

8170
# Graph Objects Errors
8271
class PlotlyGraphObjectError(PlotlyError):
83-
def __init__(self, message='', path=None, notes=None, plain_message=''):
72+
def __init__(self, message='', path=(), notes=()):
73+
"""
74+
General graph object error for validation failures.
75+
76+
:param (str|unicode) message: The error message.
77+
:param (iterable) path: A path pointing to the error.
78+
:param notes: Add additional notes, but keep default exception message.
79+
80+
"""
8481
self.message = message
85-
self.plain_message=plain_message
86-
if isinstance(path, list):
87-
self.path = path
88-
elif path is None:
89-
self.path = []
90-
else:
91-
self.path = [path]
92-
if isinstance(notes, list):
93-
self.notes = notes
94-
elif notes is None:
95-
self.notes = []
96-
else:
97-
self.notes = [notes]
82+
self.plain_message = message # for backwards compat
83+
self.path = list(path)
84+
self.notes = notes
9885
super(PlotlyGraphObjectError, self).__init__(message)
99-
self.prepare()
100-
101-
def add_note(self, note):
102-
if isinstance(note, list):
103-
self.notes += note
104-
else:
105-
self.notes += [note]
10686

107-
def add_to_error_path(self, path):
108-
if isinstance(path, list):
109-
self.path = path + self.path
110-
else:
111-
self.path = [path] + self.path
112-
113-
def prepare(self):
114-
message = self.message
115-
message += "\n\nPath To Error:\n["
116-
for iii, key in enumerate(self.path):
117-
message += repr(key)
118-
if iii < len(self.path) - 1:
119-
message += "]["
120-
message += "]"
121-
if len(self.notes):
122-
message += "\n\nAdditional Notes:\n{0}".format(
123-
"\n".join(self.notes))
124-
if len(self.args) > 1:
125-
self.args = (message, self.args[1:][0])
126-
else:
127-
self.args = message,
87+
def __str__(self):
88+
"""This is called by Python to present the error message."""
89+
format_dict = {
90+
'message': self.message,
91+
'path': '[' + ']['.join(repr(k) for k in self.path) + ']',
92+
'notes': '\n'.join(self.notes)
93+
}
94+
return ('{message}\n\nPath To Error: {path}\n\n{notes}'
95+
.format(**format_dict))
12896

12997

13098
class PlotlyDictKeyError(PlotlyGraphObjectError):
131-
def __init__(self, obj='', key='', **kwargs):
132-
message = (
133-
"Invalid key, '{key}', for class, '{obj_name}'.\n\nRun "
134-
"'help(plotly.graph_objs.{obj_name})' for more information."
135-
"".format(key=key, obj_name=obj.__class__.__name__)
99+
def __init__(self, obj, path, notes=()):
100+
"""See PlotlyGraphObjectError.__init__ for param docs."""
101+
format_dict = {'attribute': path[-1], 'object_name': obj._name}
102+
message = ("'{attribute}' is not allowed in '{object_name}'"
103+
.format(**format_dict))
104+
notes = [obj.help(return_help=True)] + list(notes)
105+
super(PlotlyDictKeyError, self).__init__(
106+
message=message, path=path, notes=notes
136107
)
137-
plain_message = ("Invalid key, '{key}', found in '{obj}' object"
138-
"".format(key=key, obj=obj.__class__.__name__))
139-
super(PlotlyDictKeyError, self).__init__(message=message,
140-
path=[key],
141-
plain_message=plain_message,
142-
**kwargs)
143108

144109

145110
class PlotlyDictValueError(PlotlyGraphObjectError):
146-
def __init__(self, obj='', key='', value='', val_types='', **kwargs):
147-
message = (
148-
"Invalid value type, '{value_name}', associated with key, "
149-
"'{key}', for class, '{obj_name}'.\nValid types for this key "
150-
"are:\n '{val_types}'.\n\nRun 'help(plotly.graph_objs.{obj_name})' "
151-
"for more information.".format(key=key,
152-
value_name=value.__class__.__name__,
153-
val_types=val_types,
154-
obj_name=obj.__class__.__name__)
111+
def __init__(self, obj, path, notes=()):
112+
"""See PlotlyGraphObjectError.__init__ for param docs."""
113+
format_dict = {'attribute': path[-1], 'object_name': obj._name}
114+
message = ("'{attribute}' has invalid value inside '{object_name}'"
115+
.format(**format_dict))
116+
notes = [obj.help(path[-1], return_help=True)] + list(notes)
117+
super(PlotlyDictValueError, self).__init__(
118+
message=message, notes=notes, path=path
155119
)
156-
plain_message = ("Invalid value found in '{obj}' associated with key, "
157-
"'{key}'".format(key=key, obj=obj.__class__.__name__))
158-
super(PlotlyDictValueError, self).__init__(message=message,
159-
plain_message=plain_message,
160-
path=[key],
161-
**kwargs)
162120

163121

164122
class PlotlyListEntryError(PlotlyGraphObjectError):
165-
def __init__(self, obj='', index='', entry='', **kwargs):
166-
message = (
167-
"The entry at index, '{0}', is invalid in a '{1}' object"
168-
"".format(index, obj.__class__.__name__)
169-
)
170-
plain_message = (
171-
"Invalid entry found in '{obj}' object at index, '{index}'."
172-
"".format(obj=obj.__class__.__name__, index=index)
123+
def __init__(self, obj, path, notes=()):
124+
"""See PlotlyGraphObjectError.__init__ for param docs."""
125+
format_dict = {'index': path[-1], 'object_name': obj._name}
126+
message = ("Invalid entry found in '{object_name}' at index, '{index}'"
127+
.format(**format_dict))
128+
notes = [obj.help(return_help=True)] + list(notes)
129+
super(PlotlyListEntryError, self).__init__(
130+
message=message, path=path, notes=notes
173131
)
174-
super(PlotlyListEntryError, self).__init__(message=message,
175-
plain_message=plain_message,
176-
path=[index],
177-
**kwargs)
178132

179133

180134
class PlotlyDataTypeError(PlotlyGraphObjectError):
181-
def __init__(self, obj='', index='', **kwargs):
182-
message = (
183-
"The entry at index, '{0}', is invalid because it does not "
184-
"contain a valid 'type' key-value. This is required for valid "
185-
"'{1}' lists.".format(index, obj.__class__.__name__)
135+
def __init__(self, obj, path, notes=()):
136+
"""See PlotlyGraphObjectError.__init__ for param docs."""
137+
format_dict = {'index': path[-1], 'object_name': obj._name}
138+
message = ("Invalid entry found in '{object_name}' at index, '{index}'"
139+
.format(**format_dict))
140+
note = "It's invalid because it does't contain a valid 'type' value."
141+
notes = [note] + list(notes)
142+
super(PlotlyDataTypeError, self).__init__(
143+
message=message, path=path, notes=notes
186144
)
187-
plain_message = (
188-
"Invalid entry found in 'data' object at index, '{0}'. It "
189-
"does not contain a valid 'type' key, required for 'data' "
190-
"lists.".format(index))
191-
super(PlotlyDataTypeError, self).__init__(message=message,
192-
plain_message=plain_message,
193-
path=[index],
194-
**kwargs)
195145

196146

197147
# Local Config Errors
@@ -201,7 +151,8 @@ class PlotlyLocalError(PlotlyError):
201151

202152
class PlotlyLocalCredentialsError(PlotlyLocalError):
203153
def __init__(self):
204-
message = ("\n"
154+
message = (
155+
"\n"
205156
"Couldn't find a 'username', 'api-key' pair for you on your local "
206157
"machine. To sign in temporarily (until you stop running Python), "
207158
"run:\n"
@@ -210,8 +161,10 @@ def __init__(self):
210161
"Even better, save your credentials permanently using the 'tools' "
211162
"module:\n"
212163
">>> import plotly.tools as tls\n"
213-
">>> tls.set_credentials_file(username='username', api_key='api-key')\n\n"
214-
"For more help, see https://plot.ly/python.\n")
164+
">>> tls.set_credentials_file(username='username', "
165+
"api_key='api-key')\n\n"
166+
"For more help, see https://plot.ly/python.\n"
167+
)
215168
super(PlotlyLocalCredentialsError, self).__init__(message)
216169

217170

0 commit comments

Comments
 (0)