Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added option to download an image of the most recent plot #494

Merged
merged 40 commits into from
Jun 15, 2016
Merged
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
d2b9880
added option to download an image of the most recent plot
yankev Jun 2, 2016
89c53db
remove an alert, change name of function
yankev Jun 2, 2016
c769ad6
updated docstring
yankev Jun 2, 2016
555d89a
removed unused variable `selected`
yankev Jun 2, 2016
6ff77d6
more docstring updates
yankev Jun 2, 2016
78fc1d7
added the ability to download plots when calling iplot
yankev Jun 3, 2016
341e87f
fixed the inline download method
yankev Jun 3, 2016
17485bc
renamed variables so tests will pass
yankev Jun 3, 2016
8eae6bd
attempt at stopping image download on future notebook openings
yankev Jun 4, 2016
ad728a3
fixed the download on refresh
yankev Jun 4, 2016
b2f9db9
fixing code to fix tests
yankev Jun 4, 2016
bdb4b85
Revert "fixing code to fix tests"
yankev Jun 4, 2016
0effa54
removed redundant return from _plot_html
yankev Jun 4, 2016
3172843
removed unused download arguments
yankev Jun 4, 2016
151f23e
providing functionality to all offline plot calls
yankev Jun 5, 2016
cae796e
pep8 and edit message in confirmation to download image
yankev Jun 5, 2016
8b39241
fixed typo
yankev Jun 5, 2016
e20da3e
ensuring the use of the correct argument names, and proper assignment…
yankev Jun 5, 2016
6abf3f9
added new arguments to docstrings
yankev Jun 5, 2016
cac15c5
changed `download_image` parameter to `image`
yankev Jun 7, 2016
a49d903
changed default value for image_filename
yankev Jun 7, 2016
f7d972c
added warning messages indicating the option to use `py.image`
yankev Jun 7, 2016
4256891
changed default filename for `download_notebook_image`
yankev Jun 7, 2016
d447ae4
add download image examples, update more default values
yankev Jun 7, 2016
bd46038
more docstring fixes and amending examples
yankev Jun 7, 2016
1c7d517
removed `download_notebook_image()` function
yankev Jun 7, 2016
f5baa3e
removed `download_notebook_image` from module init
yankev Jun 7, 2016
dbbad22
merged image and format into one parameter: image
yankev Jun 8, 2016
5bf4dd5
added new logic to deal with the new image parameter (iplot, plot)
yankev Jun 10, 2016
1892ab6
rename some arguments, typos, and formatting
yankev Jun 10, 2016
94a55f9
added confirm message to iplot mode
yankev Jun 10, 2016
6ea4e6d
edit value error
yankev Jun 10, 2016
e60a5dd
put download scripts into a function
yankev Jun 10, 2016
f44ad45
remove old scripts replaced by function calls
yankev Jun 10, 2016
e943120
remove image server warnings
yankev Jun 10, 2016
7b4681a
address PR comments
yankev Jun 14, 2016
0582283
fixed function names, as well as added a better check for the caller …
yankev Jun 14, 2016
8689112
Revert "fixed function names, as well as added a better check for the…
yankev Jun 14, 2016
cf90fba
renamed calls to `get_image_download_script` and fixed docstring
yankev Jun 14, 2016
4235cd4
fix ValueError message
yankev Jun 14, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 141 additions & 10 deletions plotly/offline/offline.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import uuid
import warnings
from pkg_resources import resource_string
import time
import webbrowser

import plotly
Expand All @@ -31,6 +32,8 @@

__PLOTLY_OFFLINE_INITIALIZED = False

__IMAGE_FORMATS = ['jpeg', 'png', 'webp', 'svg']


def download_plotlyjs(download_url):
warnings.warn('''
Expand All @@ -46,6 +49,49 @@ def get_plotlyjs():
plotlyjs = resource_string('plotly', path).decode('utf-8')
return plotlyjs

def get_image_download_script(caller):
"""
This function will return a script that will download an image of a Plotly
plot.

Keyword Arguments:
caller ('plot', 'iplot') -- specifies which function made the call for the
download script. If `iplot`, then an extra condition is added into the
download script to ensure that download prompts aren't initiated on
page reloads.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice 🎎!

"""

if caller == 'iplot':
check_start = 'if(document.readyState == \'complete\') {{'
check_end = '}}'
elif caller == 'plot':
check_start = ''
check_end = ''
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐄

else:
    raise SomeException( .. )

?

else:
raise ValueError('caller should only be one of `iplot` or `plot`')

return(
('<script>'
'function downloadimage(format, height, width,'
' filename) {{'
'var p = document.getElementById(\'{plot_id}\');'
'Plotly.downloadImage(p, {{format: format, height: height, '
'width: width, filename: filename}});'
'}};' +
check_start +
'if(confirm(\'Do you want to save this image as '
'{filename}.{format}?\\n\\n'
'For higher resolution images and more export options, '
'consider making requests to our image servers. Type: '
'help(py.image) for more details.'
'\')) {{'
'downloadimage(\'{format}\', {height}, {width}, '
'\'{filename}\');}}' +
check_end +
'</script>'
)
)


def init_notebook_mode(connected=False):
"""
Expand Down Expand Up @@ -114,8 +160,8 @@ def init_notebook_mode(connected=False):
__PLOTLY_OFFLINE_INITIALIZED = True


def _plot_html(figure_or_data, show_link, link_text,
validate, default_width, default_height, global_requirejs):
def _plot_html(figure_or_data, show_link, link_text, validate,
default_width, default_height, global_requirejs):

figure = tools.return_figure_from_figure_or_data(figure_or_data, validate)

Expand Down Expand Up @@ -185,9 +231,9 @@ def _plot_html(figure_or_data, show_link, link_text,

return plotly_html_div, plotdivid, width, height


def iplot(figure_or_data, show_link=True, link_text='Export to plot.ly',
validate=True):
validate=True, image=None, filename='plot_image', image_width=800,
image_height=600):
"""
Draw plotly graphs inside an IPython notebook without
connecting to an external server.
Expand All @@ -210,12 +256,23 @@ def iplot(figure_or_data, show_link=True, link_text='Export to plot.ly',
has become outdated with your version of
graph_reference.json or if you need to include
extra, unnecessary keys in your figure.
image (default=None |'png' |'jpeg' |'svg' |'webp') -- This parameter sets
the format of the image to be downloaded, if we choose to download an
image. This parameter has a default value of None indicating that no
image should be downloaded.
filename (default='plot') -- Sets the name of the file your image
will be saved to. The extension should not be included.
image_height (default=600) -- Specifies the height of the image in `px`.
image_width (default=800) -- Specifies the width of the image in `px`.

Example:
```
from plotly.offline import init_notebook_mode, iplot
init_notebook_mode()
iplot([{'x': [1, 2, 3], 'y': [5, 2, 7]}])
# We can also download an image of the plot by setting the image to the
format you want. e.g. `image='png'`
iplot([{'x': [1, 2, 3], 'y': [5, 2, 7]}], image='png')
```
"""
if not __PLOTLY_OFFLINE_INITIALIZED:
Expand All @@ -236,13 +293,30 @@ def iplot(figure_or_data, show_link=True, link_text='Export to plot.ly',

display(HTML(plot_html))

if image:
if image not in __IMAGE_FORMATS:
raise ValueError('The image parameter must be one of the following'
': {}'.format(__IMAGE_FORMATS)
)
# if image is given, and is a valid format, we will download the image
script = get_image_download_script('iplot').format(format=image,
width=image_width,
height=image_height,
filename=filename,
plot_id=plotdivid)
# allow time for the plot to draw
time.sleep(1)
Copy link
Contributor

@theengineear theengineear Jun 8, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this work for plots that take > 1 second to download draw?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right so this is a bit of a concern. The most complicated plot I tried was one with 300 boxplots, I also dropped time.sleep to 0.1 and there was no issue. I'm not really sure of a way to guarantee this success though.

# inject code to download an image of the plot
display(HTML(script))


def plot(figure_or_data,
show_link=True, link_text='Export to plot.ly',
validate=True, output_type='file',
include_plotlyjs=True,
filename='temp-plot.html',
auto_open=True):
filename='temp-plot.html', auto_open=True,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This won't flake if you don't supply a filename twice, right? Will we end up with temp-plot.html (1) or something? Or, does the OS just handle it?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, nvm, looks like this was here before your changes. 👍

image=None, image_filename='plot_image',
image_width=800, image_height=600):
""" Create a plotly graph locally as an HTML document or string.

Example:
Expand All @@ -251,6 +325,10 @@ def plot(figure_or_data,
import plotly.graph_objs as go

plot([go.Scatter(x=[1, 2, 3], y=[3, 2, 6])], filename='my-graph.html')
# We can also download an image of the plot by setting the image parameter
# to the image format we want
plot([go.Scatter(x=[1, 2, 3], y=[3, 2, 6])], filename='my-graph.html'
image='jpeg')
```
More examples below.

Expand Down Expand Up @@ -288,6 +366,14 @@ def plot(figure_or_data,
auto_open (default=True) -- If True, open the saved file in a
web browser after saving.
This argument only applies if `output_type` is 'file'.
image (default=None |'png' |'jpeg' |'svg' |'webp') -- This parameter sets
the format of the image to be downloaded, if we choose to download an
image. This parameter has a default value of None indicating that no
image should be downloaded.
image_filename (default='plot_image') -- Sets the name of the file your image
will be saved to. The extension should not be included.
image_height (default=600) -- Specifies the height of the image in `px`.
image_width (default=800) -- Specifies the width of the image in `px`.
"""
if output_type not in ['div', 'file']:
raise ValueError(
Expand Down Expand Up @@ -325,13 +411,30 @@ def plot(figure_or_data,
else:
plotly_js_script = ''

if image:
if image not in __IMAGE_FORMATS:
raise ValueError('The image parameter must be one of the '
'following: {}'.format(__IMAGE_FORMATS)
)
# if the check passes then download script is injected.
# write the download script:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

script = get_image_download_script('plot')
script = script.format(format=image,
width=image_width,
height=image_height,
filename=image_filename,
plot_id=plotdivid)
else:
script = ''

f.write(''.join([
'<html>',
'<head><meta charset="utf-8" /></head>',
'<body>',
plotly_js_script,
plot_html,
resize_script,
script,
'</body>',
'</html>']))

Expand All @@ -358,7 +461,9 @@ def plot(figure_or_data,
def plot_mpl(mpl_fig, resize=False, strip_style=False,
verbose=False, show_link=True, link_text='Export to plot.ly',
validate=True, output_type='file', include_plotlyjs=True,
filename='temp-plot.html', auto_open=True):
filename='temp-plot.html', auto_open=True,
image=None, image_filename='plot_image',
image_height=600, image_width=800):
"""
Convert a matplotlib figure to a Plotly graph stored locally as HTML.

Expand Down Expand Up @@ -402,6 +507,14 @@ def plot_mpl(mpl_fig, resize=False, strip_style=False,
auto_open (default=True) -- If True, open the saved file in a
web browser after saving.
This argument only applies if `output_type` is 'file'.
image (default=None |'png' |'jpeg' |'svg' |'webp') -- This parameter sets
the format of the image to be downloaded, if we choose to download an
image. This parameter has a default value of None indicating that no
image should be downloaded.
image_filename (default='plot_image') -- Sets the name of the file your
image will be saved to. The extension should not be included.
image_height (default=600) -- Specifies the height of the image in `px`.
image_width (default=800) -- Specifies the width of the image in `px`.

Example:
```
Expand All @@ -416,16 +529,22 @@ def plot_mpl(mpl_fig, resize=False, strip_style=False,
plt.plot(x, y, "o")

plot_mpl(fig)
# If you want to to download an image of the figure as well
plot_mpl(fig, image='png')
```
"""
plotly_plot = tools.mpl_to_plotly(mpl_fig, resize, strip_style, verbose)
return plot(plotly_plot, show_link, link_text, validate, output_type,
include_plotlyjs, filename, auto_open)
include_plotlyjs, filename, auto_open,
image=image, image_filename=image_filename,
image_height=image_height, image_width=image_width)


def iplot_mpl(mpl_fig, resize=False, strip_style=False,
verbose=False, show_link=True,
link_text='Export to plot.ly', validate=True):
link_text='Export to plot.ly', validate=True,
image=None, image_filename='plot_image',
image_height=600, image_width=800):
"""
Convert a matplotlib figure to a plotly graph and plot inside an IPython
notebook without connecting to an external server.
Expand Down Expand Up @@ -454,6 +573,14 @@ def iplot_mpl(mpl_fig, resize=False, strip_style=False,
has become outdated with your version of
graph_reference.json or if you need to include
extra, unnecessary keys in your figure.
image (default=None |'png' |'jpeg' |'svg' |'webp') -- This parameter sets
the format of the image to be downloaded, if we choose to download an
image. This parameter has a default value of None indicating that no
image should be downloaded.
image_filename (default='plot_image') -- Sets the name of the file your
image will be saved to. The extension should not be included.
image_height (default=600) -- Specifies the height of the image in `px`.
image_width (default=800) -- Specifies the width of the image in `px`.

Example:
```
Expand All @@ -467,10 +594,14 @@ def iplot_mpl(mpl_fig, resize=False, strip_style=False,

init_notebook_mode()
iplot_mpl(fig)
# and if you want to download an image of the figure as well
iplot_mpl(fig, image='jpeg')
```
"""
plotly_plot = tools.mpl_to_plotly(mpl_fig, resize, strip_style, verbose)
return iplot(plotly_plot, show_link, link_text, validate)
return iplot(plotly_plot, show_link, link_text, validate,
image=image, filename=image_filename,
image_height=image_height, image_width=image_width)


def enable_mpl_offline(resize=False, strip_style=False,
Expand Down