Show More
@@ -190,7 +190,7 b' def display_pretty(*objs, **kwargs):' | |||||
190 |
|
190 | |||
191 | def display_html(*objs, **kwargs): |
|
191 | def display_html(*objs, **kwargs): | |
192 | """Display the HTML representation of an object. |
|
192 | """Display the HTML representation of an object. | |
193 |
|
193 | |||
194 | Note: If raw=False and the object does not have a HTML |
|
194 | Note: If raw=False and the object does not have a HTML | |
195 | representation, no HTML will be shown. |
|
195 | representation, no HTML will be shown. | |
196 |
|
196 | |||
@@ -513,13 +513,35 b' class SVG(DisplayObject):' | |||||
513 |
|
513 | |||
514 | class JSON(DisplayObject): |
|
514 | class JSON(DisplayObject): | |
515 | """JSON expects a JSON-able dict or list |
|
515 | """JSON expects a JSON-able dict or list | |
516 |
|
516 | |||
517 | not an already-serialized JSON string. |
|
517 | not an already-serialized JSON string. | |
518 |
|
518 | |||
519 | Scalar types (None, number, string) are not allowed, only dict or list containers. |
|
519 | Scalar types (None, number, string) are not allowed, only dict or list containers. | |
520 | """ |
|
520 | """ | |
521 | # wrap data in a property, which warns about passing already-serialized JSON |
|
521 | # wrap data in a property, which warns about passing already-serialized JSON | |
522 | _data = None |
|
522 | _data = None | |
|
523 | def __init__(self, data=None, url=None, filename=None, expanded=False, metadata=None): | |||
|
524 | """Create a JSON display object given raw data. | |||
|
525 | ||||
|
526 | Parameters | |||
|
527 | ---------- | |||
|
528 | data : dict or list | |||
|
529 | JSON data to display. Not an already-serialized JSON string. | |||
|
530 | Scalar types (None, number, string) are not allowed, only dict | |||
|
531 | or list containers. | |||
|
532 | url : unicode | |||
|
533 | A URL to download the data from. | |||
|
534 | filename : unicode | |||
|
535 | Path to a local file to load the data from. | |||
|
536 | expanded : boolean | |||
|
537 | Metadata to control whether a JSON display component is expanded. | |||
|
538 | metadata: dict | |||
|
539 | Specify extra metadata to attach to the json display object. | |||
|
540 | """ | |||
|
541 | self.expanded = expanded | |||
|
542 | self.metadata = metadata | |||
|
543 | super(JSON, self).__init__(data=data, url=url, filename=filename) | |||
|
544 | ||||
523 | def _check_data(self): |
|
545 | def _check_data(self): | |
524 | if self.data is not None and not isinstance(self.data, (dict, list)): |
|
546 | if self.data is not None and not isinstance(self.data, (dict, list)): | |
525 | raise TypeError("%s expects JSONable dict or list, not %r" % (self.__class__.__name__, self.data)) |
|
547 | raise TypeError("%s expects JSONable dict or list, not %r" % (self.__class__.__name__, self.data)) | |
@@ -527,7 +549,7 b' class JSON(DisplayObject):' | |||||
527 | @property |
|
549 | @property | |
528 | def data(self): |
|
550 | def data(self): | |
529 | return self._data |
|
551 | return self._data | |
530 |
|
552 | |||
531 | @data.setter |
|
553 | @data.setter | |
532 | def data(self, data): |
|
554 | def data(self, data): | |
533 | if isinstance(data, string_types): |
|
555 | if isinstance(data, string_types): | |
@@ -535,8 +557,14 b' class JSON(DisplayObject):' | |||||
535 | data = json.loads(data) |
|
557 | data = json.loads(data) | |
536 | self._data = data |
|
558 | self._data = data | |
537 |
|
559 | |||
|
560 | def _data_and_metadata(self): | |||
|
561 | md = {'expanded': self.expanded} | |||
|
562 | if self.metadata: | |||
|
563 | md.update(self.metadata) | |||
|
564 | return self.data, md | |||
|
565 | ||||
538 | def _repr_json_(self): |
|
566 | def _repr_json_(self): | |
539 | return self.data |
|
567 | return self._data_and_metadata() | |
540 |
|
568 | |||
541 | css_t = """$("head").append($("<link/>").attr({ |
|
569 | css_t = """$("head").append($("<link/>").attr({ | |
542 | rel: "stylesheet", |
|
570 | rel: "stylesheet", | |
@@ -562,7 +590,7 b' class Javascript(TextDisplayObject):' | |||||
562 |
|
590 | |||
563 | In the Notebook, the containing element will be available as `element`, |
|
591 | In the Notebook, the containing element will be available as `element`, | |
564 | and jQuery will be available. Content appended to `element` will be |
|
592 | and jQuery will be available. Content appended to `element` will be | |
565 |
visible in the output area. |
|
593 | visible in the output area. | |
566 |
|
594 | |||
567 | Parameters |
|
595 | Parameters | |
568 | ---------- |
|
596 | ---------- | |
@@ -622,7 +650,7 b' def _pngxy(data):' | |||||
622 | def _jpegxy(data): |
|
650 | def _jpegxy(data): | |
623 | """read the (width, height) from a JPEG header""" |
|
651 | """read the (width, height) from a JPEG header""" | |
624 | # adapted from http://www.64lines.com/jpeg-width-height |
|
652 | # adapted from http://www.64lines.com/jpeg-width-height | |
625 |
|
653 | |||
626 | idx = 4 |
|
654 | idx = 4 | |
627 | while True: |
|
655 | while True: | |
628 | block_size = struct.unpack('>H', data[idx:idx+2])[0] |
|
656 | block_size = struct.unpack('>H', data[idx:idx+2])[0] | |
@@ -755,10 +783,10 b' class Image(DisplayObject):' | |||||
755 | self.unconfined = unconfined |
|
783 | self.unconfined = unconfined | |
756 | self.metadata = metadata |
|
784 | self.metadata = metadata | |
757 | super(Image, self).__init__(data=data, url=url, filename=filename) |
|
785 | super(Image, self).__init__(data=data, url=url, filename=filename) | |
758 |
|
786 | |||
759 | if retina: |
|
787 | if retina: | |
760 | self._retina_shape() |
|
788 | self._retina_shape() | |
761 |
|
789 | |||
762 | def _retina_shape(self): |
|
790 | def _retina_shape(self): | |
763 | """load pixel-doubled width and height from image data""" |
|
791 | """load pixel-doubled width and height from image data""" | |
764 | if not self.embed: |
|
792 | if not self.embed: | |
@@ -872,7 +900,7 b' class Video(DisplayObject):' | |||||
872 | elif os.path.exists(data): |
|
900 | elif os.path.exists(data): | |
873 | filename = data |
|
901 | filename = data | |
874 | data = None |
|
902 | data = None | |
875 |
|
903 | |||
876 | if data and not embed: |
|
904 | if data and not embed: | |
877 | msg = ''.join([ |
|
905 | msg = ''.join([ | |
878 | "To embed videos, you must pass embed=True ", |
|
906 | "To embed videos, you must pass embed=True ", | |
@@ -894,13 +922,13 b' class Video(DisplayObject):' | |||||
894 | Your browser does not support the <code>video</code> element. |
|
922 | Your browser does not support the <code>video</code> element. | |
895 | </video>""".format(url) |
|
923 | </video>""".format(url) | |
896 | return output |
|
924 | return output | |
897 |
|
925 | |||
898 | # Embedded videos are base64-encoded. |
|
926 | # Embedded videos are base64-encoded. | |
899 | mimetype = self.mimetype |
|
927 | mimetype = self.mimetype | |
900 | if self.filename is not None: |
|
928 | if self.filename is not None: | |
901 | if not mimetype: |
|
929 | if not mimetype: | |
902 | mimetype, _ = mimetypes.guess_type(self.filename) |
|
930 | mimetype, _ = mimetypes.guess_type(self.filename) | |
903 |
|
931 | |||
904 | with open(self.filename, 'rb') as f: |
|
932 | with open(self.filename, 'rb') as f: | |
905 | video = f.read() |
|
933 | video = f.read() | |
906 | else: |
|
934 | else: | |
@@ -910,7 +938,7 b' class Video(DisplayObject):' | |||||
910 | b64_video = video |
|
938 | b64_video = video | |
911 | else: |
|
939 | else: | |
912 | b64_video = base64_encode(video).decode('ascii').rstrip() |
|
940 | b64_video = base64_encode(video).decode('ascii').rstrip() | |
913 |
|
941 | |||
914 | output = """<video controls> |
|
942 | output = """<video controls> | |
915 | <source src="data:{0};base64,{1}" type="{0}"> |
|
943 | <source src="data:{0};base64,{1}" type="{0}"> | |
916 | Your browser does not support the video tag. |
|
944 | Your browser does not support the video tag. | |
@@ -954,7 +982,7 b' def set_matplotlib_formats(*formats, **kwargs):' | |||||
954 | In [1]: set_matplotlib_formats('png', 'jpeg', quality=90) |
|
982 | In [1]: set_matplotlib_formats('png', 'jpeg', quality=90) | |
955 |
|
983 | |||
956 | To set this in your config files use the following:: |
|
984 | To set this in your config files use the following:: | |
957 |
|
985 | |||
958 | c.InlineBackend.figure_formats = {'png', 'jpeg'} |
|
986 | c.InlineBackend.figure_formats = {'png', 'jpeg'} | |
959 | c.InlineBackend.print_figure_kwargs.update({'quality' : 90}) |
|
987 | c.InlineBackend.print_figure_kwargs.update({'quality' : 90}) | |
960 |
|
988 | |||
@@ -979,19 +1007,19 b' def set_matplotlib_formats(*formats, **kwargs):' | |||||
979 | @skip_doctest |
|
1007 | @skip_doctest | |
980 | def set_matplotlib_close(close=True): |
|
1008 | def set_matplotlib_close(close=True): | |
981 | """Set whether the inline backend closes all figures automatically or not. |
|
1009 | """Set whether the inline backend closes all figures automatically or not. | |
982 |
|
1010 | |||
983 | By default, the inline backend used in the IPython Notebook will close all |
|
1011 | By default, the inline backend used in the IPython Notebook will close all | |
984 | matplotlib figures automatically after each cell is run. This means that |
|
1012 | matplotlib figures automatically after each cell is run. This means that | |
985 | plots in different cells won't interfere. Sometimes, you may want to make |
|
1013 | plots in different cells won't interfere. Sometimes, you may want to make | |
986 | a plot in one cell and then refine it in later cells. This can be accomplished |
|
1014 | a plot in one cell and then refine it in later cells. This can be accomplished | |
987 | by:: |
|
1015 | by:: | |
988 |
|
1016 | |||
989 | In [1]: set_matplotlib_close(False) |
|
1017 | In [1]: set_matplotlib_close(False) | |
990 |
|
1018 | |||
991 | To set this in your config files use the following:: |
|
1019 | To set this in your config files use the following:: | |
992 |
|
1020 | |||
993 | c.InlineBackend.close_figures = False |
|
1021 | c.InlineBackend.close_figures = False | |
994 |
|
1022 | |||
995 | Parameters |
|
1023 | Parameters | |
996 | ---------- |
|
1024 | ---------- | |
997 | close : bool |
|
1025 | close : bool | |
@@ -1001,4 +1029,3 b' def set_matplotlib_close(close=True):' | |||||
1001 | from ipykernel.pylab.config import InlineBackend |
|
1029 | from ipykernel.pylab.config import InlineBackend | |
1002 | cfg = InlineBackend.instance() |
|
1030 | cfg = InlineBackend.instance() | |
1003 | cfg.close_figures = close |
|
1031 | cfg.close_figures = close | |
1004 |
|
@@ -66,7 +66,7 b' def test_image_filename_defaults():' | |||||
66 | def _get_inline_config(): |
|
66 | def _get_inline_config(): | |
67 | from ipykernel.pylab.config import InlineBackend |
|
67 | from ipykernel.pylab.config import InlineBackend | |
68 | return InlineBackend.instance() |
|
68 | return InlineBackend.instance() | |
69 |
|
69 | |||
70 | @dec.skip_without('matplotlib') |
|
70 | @dec.skip_without('matplotlib') | |
71 | def test_set_matplotlib_close(): |
|
71 | def test_set_matplotlib_close(): | |
72 | cfg = _get_inline_config() |
|
72 | cfg = _get_inline_config() | |
@@ -135,24 +135,32 b' def test_displayobject_repr():' | |||||
135 | def test_json(): |
|
135 | def test_json(): | |
136 | d = {'a': 5} |
|
136 | d = {'a': 5} | |
137 | lis = [d] |
|
137 | lis = [d] | |
|
138 | md = {'expanded': False} | |||
|
139 | md2 = {'expanded': True} | |||
138 | j = display.JSON(d) |
|
140 | j = display.JSON(d) | |
139 | nt.assert_equal(j._repr_json_(), d) |
|
141 | j2 = display.JSON(d, expanded=True) | |
140 |
|
142 | nt.assert_equal(j._repr_json_(), (d, md)) | ||
|
143 | nt.assert_equal(j2._repr_json_(), (d, md2)) | |||
|
144 | ||||
141 | with warnings.catch_warnings(record=True) as w: |
|
145 | with warnings.catch_warnings(record=True) as w: | |
142 | warnings.simplefilter("always") |
|
146 | warnings.simplefilter("always") | |
143 | j = display.JSON(json.dumps(d)) |
|
147 | j = display.JSON(json.dumps(d)) | |
144 | nt.assert_equal(len(w), 1) |
|
148 | nt.assert_equal(len(w), 1) | |
145 | nt.assert_equal(j._repr_json_(), d) |
|
149 | nt.assert_equal(j._repr_json_(), (d, md)) | |
146 |
|
150 | nt.assert_equal(j2._repr_json_(), (d, md2)) | ||
|
151 | ||||
147 | j = display.JSON(lis) |
|
152 | j = display.JSON(lis) | |
148 | nt.assert_equal(j._repr_json_(), lis) |
|
153 | j2 = display.JSON(lis, expanded=True) | |
149 |
|
154 | nt.assert_equal(j._repr_json_(), (lis, md)) | ||
|
155 | nt.assert_equal(j2._repr_json_(), (lis, md2)) | |||
|
156 | ||||
150 | with warnings.catch_warnings(record=True) as w: |
|
157 | with warnings.catch_warnings(record=True) as w: | |
151 | warnings.simplefilter("always") |
|
158 | warnings.simplefilter("always") | |
152 | j = display.JSON(json.dumps(lis)) |
|
159 | j = display.JSON(json.dumps(lis)) | |
153 | nt.assert_equal(len(w), 1) |
|
160 | nt.assert_equal(len(w), 1) | |
154 | nt.assert_equal(j._repr_json_(), lis) |
|
161 | nt.assert_equal(j._repr_json_(), (lis, md)) | |
155 |
|
162 | nt.assert_equal(j2._repr_json_(), (lis, md2)) | ||
|
163 | ||||
156 | def test_video_embedding(): |
|
164 | def test_video_embedding(): | |
157 | """use a tempfile, with dummy-data, to ensure that video embedding doesn't crash""" |
|
165 | """use a tempfile, with dummy-data, to ensure that video embedding doesn't crash""" | |
158 | v = display.Video("http://ignored") |
|
166 | v = display.Video("http://ignored") | |
@@ -172,15 +180,15 b' def test_video_embedding():' | |||||
172 | assert not v.embed |
|
180 | assert not v.embed | |
173 | html = v._repr_html_() |
|
181 | html = v._repr_html_() | |
174 | nt.assert_not_in('src="data:', html) |
|
182 | nt.assert_not_in('src="data:', html) | |
175 |
|
183 | |||
176 | v = display.Video(f.name, embed=True) |
|
184 | v = display.Video(f.name, embed=True) | |
177 | html = v._repr_html_() |
|
185 | html = v._repr_html_() | |
178 | nt.assert_in('src="data:video/mp4;base64,YWJj"',html) |
|
186 | nt.assert_in('src="data:video/mp4;base64,YWJj"',html) | |
179 |
|
187 | |||
180 | v = display.Video(f.name, embed=True, mimetype='video/other') |
|
188 | v = display.Video(f.name, embed=True, mimetype='video/other') | |
181 | html = v._repr_html_() |
|
189 | html = v._repr_html_() | |
182 | nt.assert_in('src="data:video/other;base64,YWJj"',html) |
|
190 | nt.assert_in('src="data:video/other;base64,YWJj"',html) | |
183 |
|
191 | |||
184 | v = display.Video(b'abc', embed=True, mimetype='video/mp4') |
|
192 | v = display.Video(b'abc', embed=True, mimetype='video/mp4') | |
185 | html = v._repr_html_() |
|
193 | html = v._repr_html_() | |
186 | nt.assert_in('src="data:video/mp4;base64,YWJj"',html) |
|
194 | nt.assert_in('src="data:video/mp4;base64,YWJj"',html) | |
@@ -188,4 +196,3 b' def test_video_embedding():' | |||||
188 | v = display.Video(u'YWJj', embed=True, mimetype='video/xyz') |
|
196 | v = display.Video(u'YWJj', embed=True, mimetype='video/xyz') | |
189 | html = v._repr_html_() |
|
197 | html = v._repr_html_() | |
190 | nt.assert_in('src="data:video/xyz;base64,YWJj"',html) |
|
198 | nt.assert_in('src="data:video/xyz;base64,YWJj"',html) | |
191 |
|
General Comments 0
You need to be logged in to leave comments.
Login now