Skip to content

Figure.savefig() reports confusing errors when saving image into a non-existent directory #2092

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

Closed
seisman opened this issue Aug 30, 2022 · 0 comments · Fixed by #2160
Closed
Labels
bug Something isn't working
Milestone

Comments

@seisman
Copy link
Member

seisman commented Aug 30, 2022

Description of the problem

Figure.savefig() reports errors when saving an image to a subdirectory that doesn't exist. The error messages are very confusing.

I think we should check if the parent directory of the image exists before saving an image. If the directory doesn't exist, we have two options:

  1. Report that parent directories are missing and users should create these directories manually
  2. Create any missing parent directories automatically before saving

Full code that generated the error

import pygmt
fig = pygmt.Figure()
fig.basemap(region=[101, 108.5, 26, 29], projection="M15c", frame=True)
fig.savefig("anypath/map.png")

Full error message

GPL Ghostscript 9.55.0: **** Could not open the file 'anypath/map.png'.
Error: /invalidfileaccess in --showpage--
Operand stack:
   1   true
Execution stack:
   %interp_exit   .runexec2   --nostringval--   showpage   --nostringval--   2   %stopped_push   --nostringval--   showpage   showpage   false   1   %stopped_push   1974   1   3   %oparray_pop   1973   1   3   %oparray_pop   1961   1   3   %oparray_pop   1817   1   3   %oparray_pop   --nostringval--   %errorexec_pop   .runexec2   --nostringval--   showpage   --nostringval--   2   %stopped_push   --nostringval--   1824   0   4   %oparray_pop   showpage   showpage
Dictionary stack:
   --dict:776/1123(ro)(G)--   --dict:0/20(G)--   --dict:75/200(L)--   --dict:158/250(L)--
Current allocation mode is local
Last OS error: No such file or directory
Current file position is 24898
GPL Ghostscript 9.55.0: Unrecoverable error, exit code 1
psconvert [ERROR]: System call [gs -q -dNOPAUSE -dBATCH -dNOSAFER -dSCANCONVERTERTYPE=2 -dMaxBitmap=2147483647 -dUseFastColor=true -dGraphicsAlphaBits=2 -dTextAlphaBits=2 -sDEVICE=png16m  -g1904x872 -r300 -sOutputFile='anypath/map.png' '/home/seisman/.gmt/sessions/gmt_session.90482/psconvert_90482d.eps'] returned error 256.
---------------------------------------------------------------------------
GMTCLibError                              Traceback (most recent call last)
Input In [6], in <cell line: 1>()
----> 1 fig.savefig("anypath/map.png")

File ~/OSS/gmt/pygmt/pygmt/figure.py:318, in Figure.savefig(self, fname, transparent, crop, anti_alias, show, **kwargs)
    315 if ext == "kml":
    316     kwargs["W"] = "+k"
--> 318 self.psconvert(prefix=prefix, fmt=fmt, crop=crop, **kwargs)
    319 if show:
    320     launch_external_viewer(fname)

File ~/OSS/gmt/pygmt/pygmt/helpers/decorators.py:585, in use_alias.<locals>.alias_decorator.<locals>.new_module(*args, **kwargs)
    580         msg = (
    581             f"Short-form parameter ({short_param}) is not recommended. "
    582             f"Use long-form parameter '{long_alias}' instead."
    583         )
    584         warnings.warn(msg, category=SyntaxWarning, stacklevel=2)
--> 585 return module_func(*args, **kwargs)

File ~/OSS/gmt/pygmt/pygmt/helpers/decorators.py:725, in kwargs_to_strings.<locals>.converter.<locals>.new_module(*args, **kwargs)
    723             kwargs[arg] = separators[fmt].join(f"{item}" for item in value)
    724 # Execute the original function and return its output
--> 725 return module_func(*args, **kwargs)

File ~/OSS/gmt/pygmt/pygmt/figure.py:251, in Figure.psconvert(self, icc_gray, **kwargs)
    248     raise GMTInvalidInput("The 'prefix' must be specified.") from err
    250 with Session() as lib:
--> 251     lib.call_module(
    252         module="psconvert", args=f"{prefix_arg} {build_arg_string(kwargs)}"
    253     )

File ~/OSS/gmt/pygmt/pygmt/clib/session.py:506, in Session.call_module(self, module, args)
    502 status = c_call_module(
    503     self.session_pointer, module.encode(), mode, args.encode()
    504 )
    505 if status != 0:
--> 506     raise GMTCLibError(
    507         f"Module '{module}' failed with status code {status}:\n{self._error_message}"
    508     )

GMTCLibError: Module 'psconvert' failed with status code 79:
psconvert [ERROR]: System call [gs -q -dNOPAUSE -dBATCH -dNOSAFER -dSCANCONVERTERTYPE=2 -dMaxBitmap=2147483647 -dUseFastColor=true -dGraphicsAlphaBits=2 -dTextAlphaBits=2 -sDEVICE=png16m  -g1904x872 -r300 -sOutputFile='anypath/map.png' '/home/seisman/.gmt/sessions/gmt_session.90482/psconvert_90482d.eps'] returned error 256.

System information

Please paste the output of python -c "import pygmt; pygmt.show_versions()":

PyGMT information:
  version: v0.7.1.dev47+gcfc20a70
System information:
  python: 3.10.5 | packaged by conda-forge | (main, Jun 14 2022, 07:04:59) [GCC 10.3.0]
  executable: /home/seisman/opt/miniconda/bin/python
  machine: Linux-5.18.11-200.fc36.x86_64-x86_64-with-glibc2.35
Dependency information:
  numpy: 1.22.4
  pandas: 1.4.2
  xarray: 2022.3.0
  netCDF4: 1.5.8
  packaging: 21.3
  geopandas: None
  ghostscript: 9.55.0
  gmt: 6.5.0_111fa6d_2022.08.11
GMT library information:
  binary dir: /home/seisman/opt/miniconda/bin
  cores: 80
  grid layout: rows
  library path: /home/seisman/opt/GMT-master/lib64/libgmt.so
  padding: 2
  plugin dir: /home/seisman/opt/GMT-master/lib64/gmt/plugins
  share dir: /home/seisman/opt/GMT-master/share
  version: 6.5.0
@seisman seisman added the bug Something isn't working label Aug 30, 2022
@seisman seisman added this to the 0.8.0 milestone Sep 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
1 participant