altair
altair copied to clipboard
Save to PNG and SVG fails on charts with images in them
Problem
When saving ~~a multi-plot~~ an image-based plot ~~created in various means~~, it cannot save in PNG or SVG formats
Details
myplot = alt.hconcat(line_plot, logo)
myplot.save('chart.png') # or 'chart.svg'
fails with the following traceback:
---------------------------------------------------------------------------
CalledProcessError Traceback (most recent call last)
in
15
16 myplot = alt.hconcat(line_plot, logo)
---> 17 myplot.save('chart.png') # or 'chart.svg'
18 #line_plot2 | logo
19
/usr/local/Caskroom/miniconda/base/envs/sdfe/lib/python3.8/site-packages/altair/vegalite/v4/api.py in save(self, fp, format, override_data_transformer, scale_factor, vegalite_version, vega_version, vegaembed_version, **kwargs)
474 if override_data_transformer:
475 with data_transformers.disable_max_rows():
--> 476 result = save(**kwds)
477 else:
478 result = save(**kwds)
/usr/local/Caskroom/miniconda/base/envs/sdfe/lib/python3.8/site-packages/altair/utils/save.py in save(chart, fp, vega_version, vegaembed_version, format, mode, vegalite_version, embed_options, json_kwds, webdriver, scale_factor, **kwargs)
110 write_file_or_filename(fp, mimebundle["text/html"], mode="w")
111 elif format in ["png", "svg"]:
--> 112 mimebundle = spec_to_mimebundle(
113 spec=spec,
114 format=format,
/usr/local/Caskroom/miniconda/base/envs/sdfe/lib/python3.8/site-packages/altair/utils/mimebundle.py in spec_to_mimebundle(spec, format, mode, vega_version, vegaembed_version, vegalite_version, **kwargs)
58 "see http://github.com/altair-viz/altair_saver/".format(fmt=format)
59 )
---> 60 return altair_saver.render(spec, format, mode=mode, **kwargs)
61 if format == "html":
62 html = spec_to_html(
/usr/local/Caskroom/miniconda/base/envs/sdfe/lib/python3.8/site-packages/altair_saver/_core.py in render(chart, fmts, mode, embed_options, method, **kwargs)
255 Saver = _select_saver(method, mode=mode, fmt=fmt)
256 saver = Saver(spec, mode=mode, embed_options=embed_options, **kwargs)
--> 257 mimebundle.update(saver.mimebundle(fmt))
258
259 return mimebundle
/usr/local/Caskroom/miniconda/base/envs/sdfe/lib/python3.8/site-packages/altair_saver/savers/_saver.py in mimebundle(self, fmts)
88 vegalite_version=self._package_versions["vega-lite"],
89 )
---> 90 bundle[mimetype] = self._serialize(fmt, "mimebundle")
91 return bundle
92
/usr/local/Caskroom/miniconda/base/envs/sdfe/lib/python3.8/site-packages/altair_saver/savers/_node.py in _serialize(self, fmt, content_type)
112
113 if self._mode == "vega-lite":
--> 114 spec = self._vl2vg(spec)
115
116 if fmt == "vega":
/usr/local/Caskroom/miniconda/base/envs/sdfe/lib/python3.8/site-packages/altair_saver/savers/_node.py in _vl2vg(self, spec)
63 vl2vg = exec_path("vl2vg")
64 vl_json = json.dumps(spec).encode()
---> 65 vg_json = check_output_with_stderr(
66 [vl2vg], input=vl_json, stderr_filter=self._stderr_filter
67 )
/usr/local/Caskroom/miniconda/base/envs/sdfe/lib/python3.8/site-packages/altair_saver/_utils.py in check_output_with_stderr(cmd, shell, input, stderr_filter)
196 """
197 try:
--> 198 ps = subprocess.run(
199 cmd,
200 shell=shell,
/usr/local/Caskroom/miniconda/base/envs/sdfe/lib/python3.8/subprocess.py in run(input, capture_output, timeout, check, *popenargs, **kwargs)
510 retcode = process.poll()
511 if check and retcode:
--> 512 raise CalledProcessError(retcode, process.args,
513 output=stdout, stderr=stderr)
514 return CompletedProcess(process.args, retcode, stdout, stderr)
CalledProcessError: Command '['/usr/local/Caskroom/miniconda/base/envs/sdfe/bin/vl2vg']' returned non-zero exit status 1.
If I try to save in either JSON
or HTML
, it works fine. If I try to save just one of the plots (ie, in this case just saving line_plot
), it works.
I have not delved too deeply because I do not understand Altair's (or Vega's) inner workings well enough, but I see that it is actually altair_saver
that is failing, when it calls the vl2vg
executable.
My computer details:
- Mac OS X Catalina, powerbook
- Jupyter or via normal Python script
Reproduce
I was able to reproduce with any of the following combinations:
Multi-Plot Type:
-
HConcatChart
-
VConcatChart
-
LayerChart
Save File Type:
-
SVG
-
PNG
Again, HTML
and JSON
are able to run without a problem. I looked at the rendered solution (eg, opening up the HTML file in a browser), and they looked fine.
Actually, when digging deeper, it seems to me, this is not due to multi-charts, but instead due to ingesting images. The other chart in my example above - the chart labelled logo
, is actually an image (the logo of a company).
If I try to save a "chart" with just the logo, it also fails. All else above is correct: it only fails on SVG and PNG, etc.
I've seen this before reported on Vega-Lite, but I can't find the issue reference right now.
Hi @lazarillo, could you able to find the solution? I am facing the same issue is there any work around for this problem? Thank you very much.
Hi @arjunkumarp9 , I am sorry. I have not been using Altair much in the last few months. I did not find a solution.
I am happy to help solve the issue, if a core member of the Altair project can help point me to where the problem might lie. I don't want to comb through everything in that long stack trace to understand the problem without at least some help from an expert. :)
Saving an Altair chart with remote and local images should work well with vl-convert
instead of altair-saver
, see https://altair-viz.github.io/user_guide/saving_charts.html#png-svg-and-pdf-format. Feel free to reopen the issue and provide a reproducible code example in case this does not solve it for you!