GenericMappingTools / pygmt

A Python interface for the Generic Mapping Tools.
https://www.pygmt.org
BSD 3-Clause "New" or "Revised" License
747 stars 216 forks source link

Module 'psconvert' failed with status code 79: psconvert [ERROR]: Cannot execute Ghostscript (gswin64c). #3366

Closed jasonhappyforver closed 1 month ago

jasonhappyforver commented 1 month ago

Description of the problem

I have recently started a new job at a different university. Thus I need to re-install some python packages, including pygmt, on my new laptop. However, I got some errors when I tried to run my previous code. The error pops up upon calling fig.show(), please see the following example and the corresponding full error message. I am aware that this error has been discussed before. After going through the previous threads on this topic, I still cannot figure it out. I appreciate it if you could help me out.

I created an environment "pygmt_home" on my 64-bit windows laptop to demonstrate the issue. Some basic information:

gs version (pygmt_home) C:\Users\MJDR5>gs -version GPL Ghostscript 10.03.1 (2024-05-02) Copyright (C) 2024 Artifex Software, Inc. All rights reserved.

gs path (pygmt_home) C:\Users\MJDR5>where gs C:\Users\MJDR5\AppData\Local\anaconda3\envs\pygmt_home\Library\bin\gs.exe

GMT version (pygmt_home) C:\Users\MJDR5>gmt -version GMT - The Generic Mapping Tools, Version 6.5.0 [64-bit] [MP] [12 cores] (c) 1991-2024 The GMT Team (https://www.generic-mapping-tools.org/team.html).

    Supported in part by the US National Science Foundation (http://www.nsf.gov/)
    and volunteers from around the world.

    GMT is distributed under the GNU LGPL License (http://www.gnu.org/licenses/lgpl.html).
    Dependencies: netCDF, GDAL, PCRE, FFTW, LAPACK, ZLIB, Ghostscript, GraphicsMagick, FFmpeg.

.... omit following lines

GMT path (pygmt_home) C:\Users\MJDR5>where gmt C:\Users\MJDR5\AppData\Local\anaconda3\envs\pygmt_home\Library\bin\gmt.exe

Some Test (pygmt_home) C:\Users\MJDR5>gmt basemap -R0/1/0/1 -JX1 -Baf -Vi -png map begin [INFORMATION]: Creating a workflow directory C:/Users/MJDR5/.gmt/sessions/gmt_session.14116 basemap [INFORMATION]: Constructing the basemap basemap [INFORMATION]: Linear projection implies y-axis distance exaggeration relative to the x-axis by a factor of 1 basemap [INFORMATION]: Auto-frame interval for x-axis (item 0): a0.2f0.1 basemap [INFORMATION]: Auto-frame interval for y-axis (item 0): a0.2f0.1 basemap [INFORMATION]: Map scale is 0.001 km per cm or 1:100. end [INFORMATION]: Process GMT figure queue: 1 figures found end [INFORMATION]: Processing GMT figure #0 [map png ] psconvert [INFORMATION]: Processing C:/Users/MJDR5/.gmt/sessions/gmt_session.14116/gmt_0.ps-... psconvert [INFORMATION]: Find HiResBoundingBox ... psconvert [INFORMATION]: Figure dimensions: Width: 49.464 points [1.74498 cm] Height: 42.426 points [1.49669 cm] psconvert [INFORMATION]: [2863.91 2868.71 2913.37 2911.14]... psconvert [INFORMATION]: An unknown psconvert setting was found but since image coordinates seem to be geographical, a linear transformation will be used. psconvert [INFORMATION]: Convert to PNG... end [INFORMATION]: Destroying the current workflow directory C:/Users/MJDR5/.gmt/sessions/gmt_session.14116

Minimal Complete Verifiable Example

import pygmt
fig = pygmt.Figure()
fig.basemap(region=[0, 1, 0, 1], projection="X5c", frame="af")
fig.show()

Full error message

psconvert [ERROR]: Cannot execute Ghostscript (gswin64c).
---------------------------------------------------------------------------
GMTCLibError                              Traceback (most recent call last)
Cell In[13], line 4
      2 fig = pygmt.Figure()
      3 fig.basemap(region=[0, 1, 0, 1], projection="X5c", frame="af")
----> 4 fig.show()

File ~\AppData\Local\anaconda3\envs\pygmt_home\Lib\site-packages\pygmt\figure.py:460, in Figure.show(self, dpi, width, method, waiting, **kwargs)
    454     if not _HAS_IPYTHON:
    455         raise GMTError(
    456             "Notebook display is selected, but IPython is not available. "
    457             "Make sure you have IPython installed, "
    458             "or run the script in a Jupyter notebook."
    459         )
--> 460     png = self._preview(
    461         fmt="png", dpi=dpi, anti_alias=True, as_bytes=True, **kwargs
    462     )
    463     IPython.display.display(IPython.display.Image(data=png, width=width))
    465 if method == "external":

File ~\AppData\Local\anaconda3\envs\pygmt_home\Lib\site-packages\pygmt\figure.py:493, in Figure._preview(self, fmt, dpi, as_bytes, **kwargs)
    472 """
    473 Grab a preview of the figure.
    474 
   (...)
    490     file. Else, it is the file content loaded as a bytes string.
    491 """
    492 fname = Path(self._preview_dir.name) / f"{self._name}.{fmt}"
--> 493 self.savefig(fname, dpi=dpi, **kwargs)
    494 if as_bytes:
    495     return fname.read_bytes()

File ~\AppData\Local\anaconda3\envs\pygmt_home\Lib\site-packages\pygmt\figure.py:372, in Figure.savefig(self, fname, transparent, crop, anti_alias, show, worldfile, **kwargs)
    367         raise GMTInvalidInput(
    368             f"Saving a world file is not supported for '{ext}' format."
    369         )
    370     kwargs["W"] = True
--> 372 self.psconvert(prefix=prefix, fmt=fmt, crop=crop, **kwargs)
    374 # Remove the .pgw world file if exists
    375 # Not necessary after GMT 6.5.0.
    376 # See upstream fix https://github.com/GenericMappingTools/gmt/pull/7865
    377 if ext == "tiff":

File ~\AppData\Local\anaconda3\envs\pygmt_home\Lib\site-packages\pygmt\helpers\decorators.py:609, in use_alias.<locals>.alias_decorator.<locals>.new_module(*args, **kwargs)
    603     msg = (
    604         "Parameters 'Y' and 'yshift' are no longer supported since v0.12.0. "
    605         "Use Figure.shift_origin(yshift=...) instead."
    606     )
    607     raise GMTInvalidInput(msg)
--> 609 return module_func(*args, **kwargs)

File ~\AppData\Local\anaconda3\envs\pygmt_home\Lib\site-packages\pygmt\helpers\decorators.py:773, in kwargs_to_strings.<locals>.converter.<locals>.new_module(*args, **kwargs)
    770             bound.arguments["kwargs"][arg] = newvalue
    772 # Execute the original function and return its output
--> 773 return module_func(*bound.args, **bound.kwargs)

File ~\AppData\Local\anaconda3\envs\pygmt_home\Lib\site-packages\pygmt\figure.py:252, in Figure.psconvert(self, **kwargs)
    247     raise FileNotFoundError(
    248         f"No such directory: '{prefix_path}', please create it first."
    249     )
    251 with Session() as lib:
--> 252     lib.call_module(module="psconvert", args=build_arg_list(kwargs))

File ~\AppData\Local\anaconda3\envs\pygmt_home\Lib\site-packages\pygmt\clib\session.py:659, in Session.call_module(self, module, args)
    657 status = c_call_module(self.session_pointer, module.encode(), mode, argv)
    658 if status != 0:
--> 659     raise GMTCLibError(
    660         f"Module '{module}' failed with status code {status}:\n{self._error_message}"
    661     )

GMTCLibError: Module 'psconvert' failed with status code 79:
psconvert [ERROR]: Cannot execute Ghostscript (gswin64c).

System information

PyGMT information:
  version: v0.12.0
System information:
  python: 3.12.4 | packaged by conda-forge | (main, Jun 17 2024, 10:04:44) [MSC v.1940 64 bit (AMD64)]
  executable: C:\Users\MJDR5\AppData\Local\anaconda3\envs\pygmt_home\python.exe
  machine: Windows-11-10.0.22631-SP0
Dependency information:
  numpy: 2.0.1
  pandas: 2.2.2
  xarray: 2024.7.0
  netCDF4: 1.7.1
  packaging: 24.1
  contextily: None
  geopandas: 1.0.1
  ipython: None
  rioxarray: None
  ghostscript: None
GMT library information:
  binary version: 6.5.0
  cores: 12
  grid layout: rows
  image layout: 
  library path: C:/Users/MJDR5/AppData/Local/anaconda3/envs/pygmt_home/Library/bin/gmt.dll
  padding: 2
  plugin dir: C:/Users/MJDR5/AppData/Local/anaconda3/envs/pygmt_home/Library/bin/gmt_plugins
  share dir: C:/Users/MJDR5/AppData/Local/anaconda3/envs/pygmt_home/Library/share/gmt
  version: 6.5.0
welcome[bot] commented 1 month ago

👋 Thanks for opening your first issue here! Please make sure you filled out the template with as much detail as possible. You might also want to take a look at our contributing guidelines and code of conduct.

seisman commented 1 month ago

gs path (pygmt_home) C:\Users\MJDR5>where gs C:\Users\MJDR5\AppData\Local\anaconda3\envs\pygmt_home\Library\bin\gs.exe

do you have gswin64c.exe or gswin32c.exe in this directory.

seisman commented 1 month ago

Please also post the output of the following script:

import pygmt
fig = pygmt.Figure()
fig.basemap(region=[0, 1, 0, 1], projection="X5c", frame="af")
pygmt.config(GMT_VERBOSE="d")
fig.show()
jasonhappyforver commented 1 month ago

Please also post the output of the following script:

import pygmt
fig = pygmt.Figure()
fig.basemap(region=[0, 1, 0, 1], projection="X5c", frame="af")
pygmt.config(GMT_VERBOSE="d")
fig.show()

gs path (pygmt_home) C:\Users\MJDR5>where gs C:\Users\MJDR5\AppData\Local\anaconda3\envs\pygmt_home\Library\bin\gs.exe

do you have gswin64c.exe or gswin32c.exe in this directory.

Thank you for your handling. I do have gswin64c.exe. (pygmt_home) C:\Users\MJDR5>where gswin64c.exe C:\Users\MJDR5\AppData\Local\anaconda3\envs\pygmt_home\Library\bin\gswin64c.exe

jasonhappyforver commented 1 month ago

Please also post the output of the following script:

import pygmt
fig = pygmt.Figure()
fig.basemap(region=[0, 1, 0, 1], projection="X5c", frame="af")
pygmt.config(GMT_VERBOSE="d")
fig.show()

gs path (pygmt_home) C:\Users\MJDR5>where gs C:\Users\MJDR5\AppData\Local\anaconda3\envs\pygmt_home\Library\bin\gs.exe

do you have gswin64c.exe or gswin32c.exe in this directory.

Thank you for your handling. I do have gswin64c.exe: (pygmt_home) C:\Users\MJDR5>where gswin64c.exe C:\Users\MJDR5\AppData\Local\anaconda3\envs\pygmt_home\Library\bin\gswin64c.exe

Following your suggestion, I ran the script, import pygmt fig = pygmt.Figure() fig.basemap(region=[0, 1, 0, 1], projection="X5c", frame="af") pygmt.config(GMT_VERBOSE="d") fig.show()

Output: gmtset [DEBUG]: gmtlib_get_graphics_item: Fig: 1 Subplot: 2 Panel: () Inset: 0 pygmt-session [DEBUG]: Exit: gmt_reload_settings pygmt-session [DEBUG]: Enter: gmtlib_plot_C_format pygmt-session [DEBUG]: Exit: gmtlib_plot_C_format pygmt-session [DEBUG]: Enter: gmtinit_get_history pygmt-session [DEBUG]: gmtlib_get_graphics_item: Fig: 1 Subplot: 2 Panel: () Inset: 0 pygmt-session [DEBUG]: Enter: gmt_hash_init pygmt-session [DEBUG]: Exit: gmt_hash_init pygmt-session [DEBUG]: Failed to release lock (Error <158>: The segment is already unlocked. ) pygmt-session [DEBUG]: Exit: gmtinit_get_history pygmt-session [DEBUG]: Initialize FFTW with 12 threads. pygmt-session [DEBUG]: GMT_Create_Session initialized GMT structure pygmt-session [DEBUG]: Shared Library # 0 (core). Path = C:/Users/MJDR5/AppData/Local/anaconda3/envs/pygmt_home/Library/bin/gmt.dll pygmt-session [DEBUG]: Loading GMT plugins from: C:/Users/MJDR5/AppData/Local/anaconda3/envs/pygmt_home/Library/bin/gmt_plugins pygmt-session [DEBUG]: Shared Library # 1 (supplements). Path = C:/Users/MJDR5/AppData/Local/anaconda3/envs/pygmt_home/Library/bin/gmt_plugins/supplements.dll pygmt-session [DEBUG]: GMT now running in modern mode [Session ID = e0ec776f5a0345c4ae07d1a702793d45] Exception ignored on calling ctypes callback function: <function Session.create..print_func at 0x000002627D9D2520> Traceback (most recent call last): File "C:\Users\MJDR5\AppData\Local\anaconda3\envs\pygmt_home\Lib\site-packages\pygmt\clib\session.py", line 387, in print_func message = message.decode().strip() ^^^^^^^^^^^^^^^^ UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe0 in position 59: invalid continuation byte pygmt-session [DEBUG]: Revised options: 087e776fa6624136990b60c25e4ee0dc - pygmt-session [DEBUG]: Exit: gmt_reload_settings pygmt-session [DEBUG]: Enter: gmtlib_plot_C_format pygmt-session [DEBUG]: Exit: gmtlib_plot_C_format pygmt-session [DEBUG]: Enter: gmtinit_get_history pygmt-session [DEBUG]: gmtlib_get_graphics_item: Fig: 1 Subplot: 2 Panel: () Inset: 0 pygmt-session [DEBUG]: Enter: gmt_hash_init pygmt-session [DEBUG]: Exit: gmt_hash_init pygmt-session [DEBUG]: Failed to release lock (Error <158>: The segment is already unlocked. ) pygmt-session [DEBUG]: Exit: gmtinit_get_history pygmt-session [DEBUG]: Initialize FFTW with 12 threads. pygmt-session [DEBUG]: GMT_Create_Session initialized GMT structure pygmt-session [DEBUG]: Shared Library # 0 (core). Path = C:/Users/MJDR5/AppData/Local/anaconda3/envs/pygmt_home/Library/bin/gmt.dll pygmt-session [DEBUG]: Loading GMT plugins from: C:/Users/MJDR5/AppData/Local/anaconda3/envs/pygmt_home/Library/bin/gmt_plugins pygmt-session [DEBUG]: Shared Library # 1 (supplements). Path = C:/Users/MJDR5/AppData/Local/anaconda3/envs/pygmt_home/Library/bin/gmt_plugins/supplements.dll pygmt-session [DEBUG]: GMT now running in modern mode [Session ID = e0ec776f5a0345c4ae07d1a702793d45] Exception ignored on calling ctypes callback function: <function Session.create..print_func at 0x000002627D9D25C0> Traceback (most recent call last): File "C:\Users\MJDR5\AppData\Local\anaconda3\envs\pygmt_home\Lib\site-packages\pygmt\clib\session.py", line 387, in print_func message = message.decode().strip() ^^^^^^^^^^^^^^^^ UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf0 in position 62: invalid continuation byte pygmt-session [DEBUG]: Revised options: -A -E300 -FC:/Users/MJDR5/AppData/Local/Temp/087e776fa6624136990b60c25e4ee0dc-preview-8hseob_z/087e776fa6624136990b60c25e4ee0dc -Qg2 -Qt2 -Tg psconvert [DEBUG]: Ghostscript not found in registry. Fallback to PATH. psconvert [DEBUG]: Ghostscript executable full name: psconvert [DEBUG]: gmt_run_process_get_first_line: Pass to popen: [gswin64c --version 2> NUL] psconvert [DEBUG]: gswin64c --version 2> NUL failed psconvert [ERROR]: Cannot execute Ghostscript (gswin64c).

Output over

Noting that:

seisman commented 1 month ago

What's the output if you run gswin64c --version or gswin64c.exe --version?

jasonhappyforver commented 1 month ago

What's the output if you run gswin64c --version or gswin64c.exe --version?

It is 10.03.1, please see below:

(pygmt_home) C:\Users\MJDR5>gswin64c --version 10.03.1

(pygmt_home) C:\Users\MJDR5>gswin64c.exe --version 10.03.1

seisman commented 1 month ago

This one is really hard to debug since we can't reproduce your issue.

Does fig.show(gs_path="C:\Users\MJDR5\AppData\Local\anaconda3\envs\pygmt_home\Library\bin\gswin64c") works?

jasonhappyforver commented 1 month ago

This one is really hard to debug since we can't reproduce your issue.

Does fig.show(gs_path="C:\Users\MJDR5\AppData\Local\anaconda3\envs\pygmt_home\Library\bin\gswin64c") works?

Yes, it worked, both fig.show and fig.save. It seems I need to specify the path in both commands. Thank you so very much.

seisman commented 1 month ago

Good to know that it works. Closing.