altair-viz / altair_saver

Altair extension for saving charts in a variety of formats.
BSD 3-Clause "New" or "Revised" License
95 stars 33 forks source link

How to debug error with method='node', fmt='png' or fmt='svg' in Ubuntu/WSL: CalledProcessError: Command '['/home/yshen/.nvm/versions/node/v16.13.1/bin/npm', 'bin', '--global']' returned non-zero exit status 1 #112

Closed yubrshen closed 1 year ago

yubrshen commented 1 year ago

I've followed the installation instruction in READM. But I keep getting this error: CalledProcessError: Command '['/home/yshen/.nvm/versions/node/v16.13.1/bin/npm', 'bin', '--global']' returned non-zero exit status 1 with the following example:

import altair as alt
from vega_datasets import data
cars = data.cars.url

chart = alt.Chart(cars).mark_bar().encode(
  x=alt.X('Miles_per_Gallon:Q', bin=True),
  y='count()',
)

chart.display()

and

from altair_saver import save
fmt = 'svg'
save(chart, f'chart.{fmt}', method='node')

Here is the full trace of the error:

CalledProcessError                        Traceback (most recent call last)
Cell In [6], line 3
      1 from altair_saver import save
      2 fmt = 'svg'
----> 3 save(chart, f'chart.{fmt}', method='node')

File /usr/local/lib/python3.10/dist-packages/altair_saver/_core.py:172, in save(chart, fp, fmt, mode, embed_options, method, suppress_data_warning, **kwargs)
    169 Saver = _select_saver(method, mode=mode, fmt=fmt, fp=fp)
    170 saver = Saver(spec, mode=mode, embed_options=embed_options, **kwargs)
--> 172 return saver.save(fp=fp, fmt=fmt)

File /usr/local/lib/python3.10/dist-packages/altair_saver/savers/_saver.py:121, in Saver.save(self, fp, fmt)
    118 if fmt not in self.valid_formats[self._mode]:
    119     raise ValueError(f"Got fmt={fmt}; expected one of {self.valid_formats}")
--> 121 content = self._serialize(fmt, "save")
    122 if fp is None:
    123     if isinstance(content, dict):

File /usr/local/lib/python3.10/dist-packages/altair_saver/savers/_node.py:114, in NodeSaver._serialize(self, fmt, content_type)
    111 spec = self._spec
    113 if self._mode == "vega-lite":
--> 114     spec = self._vl2vg(spec)
    116 if fmt == "vega":
    117     return spec

File /usr/local/lib/python3.10/dist-packages/altair_saver/savers/_node.py:63, in NodeSaver._vl2vg(self, spec)
     61 def _vl2vg(self, spec: JSONDict) -> JSONDict:
     62     """Compile a Vega-Lite spec into a Vega 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     )

File /usr/local/lib/python3.10/dist-packages/altair_saver/savers/_node.py:29, in exec_path(name)
     27 @functools.lru_cache(16)
     28 def exec_path(name: str) -> str:
---> 29     for path in [None, npm_bin(global_=True), npm_bin(global_=False)]:
     30         exc = shutil.which(name, path=path)
     31         if exc:

File /usr/local/lib/python3.10/dist-packages/altair_saver/savers/_node.py:24, in npm_bin(global_)
     22 if global_:
     23     cmd.append("--global")
---> 24 return check_output_with_stderr(cmd).decode().strip()

File /usr/local/lib/python3.10/dist-packages/altair_saver/_utils.py:198, in check_output_with_stderr(cmd, shell, input, stderr_filter)
    176 """Run a command in a subprocess, printing stderr to sys.stderr.
    177 
    178 This function exists because normally, stderr from subprocess in the notebook
   (...)
    195 subprocess.CalledProcessError : if the called process returns a non-zero exit code.
    196 """
    197 try:
--> 198     ps = subprocess.run(
    199         cmd,
    200         shell=shell,
    201         input=input,
    202         check=True,
    203         stdout=subprocess.PIPE,
    204         stderr=subprocess.PIPE,
    205     )
    206 except subprocess.CalledProcessError as err:
    207     stderr = err.stderr

File /usr/lib/python3.10/subprocess.py:524, in run(input, capture_output, timeout, check, *popenargs, **kwargs)
    522     retcode = process.poll()
    523     if check and retcode:
--> 524         raise CalledProcessError(retcode, process.args,
    525                                  output=stdout, stderr=stderr)
    526 return CompletedProcess(process.args, retcode, stdout, stderr)

CalledProcessError: Command '['/home/yshen/.nvm/versions/node/v16.13.1/bin/npm', 'bin', '--global']' returned non-zero exit status 1.

I thought the command executed would be npm bin --globalbased on the following: '['/home/yshen/.nvm/versions/node/v16.13.1/bin/npm', 'bin', '--global']' but it is not even a command. Maybe my interpretation is wrong? As I'm running in Ubuntu/WSL, where chromium does not work, I have to use node as backend.

yubrshen commented 1 year ago

The problem has been resolved. I had to create a fresh environment only using the following command: conda install -c conda-forge altair_saver to setup altair_saver.