diff --git a/doc/changelog.d/4196.miscellaneous.md b/doc/changelog.d/4196.miscellaneous.md new file mode 100644 index 0000000000..d04b5039df --- /dev/null +++ b/doc/changelog.d/4196.miscellaneous.md @@ -0,0 +1 @@ +Use screenshot to show plots diff --git a/src/ansys/mapdl/core/mapdl_core.py b/src/ansys/mapdl/core/mapdl_core.py index 320e84abed..4ae193cbcf 100644 --- a/src/ansys/mapdl/core/mapdl_core.py +++ b/src/ansys/mapdl/core/mapdl_core.py @@ -28,7 +28,7 @@ import os import pathlib import re -from shutil import copy, copyfile, rmtree +from shutil import copyfile, rmtree # Subprocess is needed to start the backend. But # the input is controlled by the library. Excluding bandit check. @@ -2323,7 +2323,7 @@ def run( # Check kwargs verbose = kwargs.pop("verbose", False) - save_fig = kwargs.pop("savefig", False) + savefig = kwargs.pop("savefig", False) # Check if you want to avoid the current non-interactive context. avoid_non_interactive = kwargs.pop("avoid_non_interactive", False) @@ -2419,14 +2419,6 @@ def run( self._log.debug(f"Running (verbose: {verbose}, mute={mute}): '{command}'") text = self._run(command, verbose=verbose, mute=mute) - if ( - "Display device has not yet been specified with the /SHOW command" in text - and short_cmd in PLOT_COMMANDS - ): - # Reissuing the command to make sure we get output. - self.show(self.default_file_type_for_plots) - text = self._run(command, verbose=verbose, mute=mute) - self._after_run(command) if mute: @@ -2447,16 +2439,7 @@ def run( # special returns for certain geometry commands if short_cmd in PLOT_COMMANDS: self._log.debug("It is a plot command.") - plot_path = self._get_plot_name(text) - - if save_fig: - return self._download_plot(plot_path, save_fig) - elif self._has_matplotlib: - return self._display_plot(plot_path) - else: - self._log.debug( - "Since matplolib is not installed, images are not shown." - ) + return self.screenshot(savefig=savefig, default_name="plot") return self._response @@ -2514,7 +2497,7 @@ def _get_plot_name(self, text: str) -> str: if os.path.isfile(filename): return filename else: # pragma: no cover - raise MapdlRuntimeError("Unable to find screenshot at %s", filename) + raise MapdlRuntimeError(f"Unable to find screenshot at {filename}") else: raise MapdlRuntimeError( "Unable to find plotted file in MAPDL command output. " @@ -2554,22 +2537,30 @@ def in_ipython(): display(plt.gcf()) - def _download_plot(self, filename: str, plot_name: str) -> None: + def _download_plot( + self, filename: str, plot_name: str, default_name: str = "plot" + ) -> None: """Copy the temporary download plot to the working directory.""" if isinstance(plot_name, str): provided = True path_ = pathlib.Path(plot_name) - plot_name = path_.name - plot_stem = path_.stem - plot_ext = path_.suffix - plot_path = str(path_.parent) - if not plot_path or plot_path == ".": - plot_path = os.getcwd() + if path_.is_dir() or path_.suffix == "": + plot_name = f"{default_name}.png" + plot_stem = default_name + plot_ext = ".png" + plot_path = str(path_) + else: + plot_name = path_.name + plot_stem = path_.stem + plot_ext = path_.suffix + plot_path = str(path_.parent) + if not plot_path or plot_path == ".": + plot_path = os.getcwd() elif isinstance(plot_name, bool): provided = False - plot_name = "plot.png" - plot_stem = "plot" + plot_name = f"{default_name}.png" + plot_stem = default_name plot_ext = ".png" plot_path = os.getcwd() else: # pragma: no cover @@ -2586,6 +2577,10 @@ def _download_plot(self, filename: str, plot_name: str) -> None: self._log.debug( f"Copy plot file from temp directory to working directory as: {plot_path}" ) + if provided: + return plot_path_ + else: + return os.path.basename(plot_path_) def _screenshot_path(self): """Return last filename based on the current jobname""" @@ -3287,7 +3282,9 @@ def list_files(self, refresh_cache: bool = True) -> List[str]: warn("No files listed") return files - def screenshot(self, savefig: Optional[str] = None): + def screenshot( + self, savefig: Optional[str] = None, default_name: str = "mapdl_screenshot" + ) -> str: """Take an MAPDL screenshot and show it in a popup window. Parameters @@ -3314,47 +3311,12 @@ def screenshot(self, savefig: Optional[str] = None): self.show(previous_device) # previous device file_name = self._get_plot_name(out_) - def get_file_name(path): - """Get a new filename so as not to overwrite an existing one.""" - target_dir = os.path.join(path, "mapdl_screenshot_0.png") - i = 0 - while os.path.exists(target_dir): - # Ensuring file is not overwritten. - i += 1 - target_dir = os.path.join(path, f"mapdl_screenshot_{i}.png") - return target_dir - - if savefig is None or savefig is False: - self._display_plot(file_name) - + if savefig: + return self._download_plot(file_name, savefig, default_name=default_name) + elif self._has_matplotlib: + return self._display_plot(file_name) else: - if savefig is True: - # Copying to working directory - target_dir = get_file_name(os.getcwd()) - - elif isinstance(savefig, str): - if not os.path.dirname(savefig): - # File name given only - target_dir = os.path.join(os.getcwd(), savefig) - - elif os.path.isdir(savefig): - # Given directory path only, but not file name. - target_dir = get_file_name(savefig) - - elif os.path.exists(os.path.dirname(savefig)): - # Only directory is given. Checking if directory exists. - target_dir = savefig - - else: - raise FileNotFoundError("The filename or path is not valid.") - - else: - raise ValueError( - "Only strings or Booleans are valid inputs for the 'savefig' parameter." - ) - - copy(file_name, target_dir) - return os.path.basename(target_dir) + self._log.debug("Since matplolib is not installed, images are not shown.") def _create_session(self): """Generate a session ID.""" diff --git a/src/ansys/mapdl/core/mapdl_grpc.py b/src/ansys/mapdl/core/mapdl_grpc.py index 50c8ee0165..555cf145f5 100644 --- a/src/ansys/mapdl/core/mapdl_grpc.py +++ b/src/ansys/mapdl/core/mapdl_grpc.py @@ -2600,11 +2600,9 @@ def _screenshot_path(self): if self._local: return super()._screenshot_path() - all_filenames = self.list_files() - filenames = [] - for filename in all_filenames: - if filename.endswith(".png"): - filenames.append(filename) + filenames = [ + filename for filename in self.list_files() if filename.endswith(".png") + ] filenames.sort() filename = os.path.basename(filenames[-1]) diff --git a/tests/test_mapdl.py b/tests/test_mapdl.py index b5154fd3a5..56ef1beb90 100644 --- a/tests/test_mapdl.py +++ b/tests/test_mapdl.py @@ -2690,7 +2690,7 @@ def test_screenshot(mapdl, make_block, tmpdir): assert "TIFF" == mapdl.file_type_for_plots file_name = mapdl.screenshot(True) - assert "mapdl_screenshot_0.png" == file_name + assert "mapdl_screenshot.png" == file_name assert "TIFF" == mapdl.file_type_for_plots assert file_name in os.listdir(os.getcwd()) @@ -2699,12 +2699,12 @@ def test_screenshot(mapdl, make_block, tmpdir): assert "TIFF" == mapdl.file_type_for_plots assert file_name in os.listdir(os.getcwd()) - os.remove("mapdl_screenshot_0.png") + os.remove("mapdl_screenshot.png") os.remove(file_name) file_name = mapdl.screenshot(str(tmpdir)) assert "TIFF" == mapdl.file_type_for_plots - assert file_name in os.listdir(str(tmpdir)) + assert os.path.basename(file_name) in os.listdir(str(tmpdir)) dest = os.path.join(tmpdir, "myscreenshot.png") file_name = mapdl.screenshot(dest) diff --git a/tests/test_plotting.py b/tests/test_plotting.py index 27b6f9b419..cd7aeec50a 100644 --- a/tests/test_plotting.py +++ b/tests/test_plotting.py @@ -167,14 +167,8 @@ def test_download_file_with_vkt_false(mapdl, cube_solve, tmpdir): mapdl.eplot(savefig="myfile.png") assert not os.path.exists("myfile_1.png") assert os.path.getmtime("myfile.png") != ti_m # file has been modified. - os.remove("myfile.png") - # Testing no extension - mapdl.eplot(savefig="myfile") - assert os.path.exists("myfile") - os.remove("myfile") - # Testing update name when file exists. mapdl.eplot(savefig=True) assert os.path.exists("plot.png") @@ -190,7 +184,7 @@ def test_download_file_with_vkt_false(mapdl, cube_solve, tmpdir): mapdl.eplot(savefig=plot_) assert os.path.exists(plot_) - plot_ = os.path.join(tmpdir, "myplot") + plot_ = os.path.join(tmpdir, "myplot.png") mapdl.eplot(savefig=plot_) assert os.path.exists(plot_) @@ -221,9 +215,12 @@ def test_kplot(cleared, mapdl, tmpdir, backend): filename = str(tmpdir.mkdir("tmpdir").join("tmp.png")) cpos = mapdl.kplot(graphics_backend=backend, savefig=filename) - assert cpos is None - if backend: - assert os.path.isfile(filename) + if backend == GraphicsBackend.MAPDL: + assert isinstance(cpos, str) + else: + assert cpos is None + + assert os.path.isfile(filename) @pytest.mark.parametrize( @@ -1054,7 +1051,7 @@ def test_file_type_for_plots(mapdl, cleared): [each for each in mapdl.list_files() if each.endswith(".png")] ) - assert n_files_ending_png_before + 1 == n_files_ending_png_after + assert n_files_ending_png_before + 2 == n_files_ending_png_after @pytest.mark.parametrize("entity", ["KP", "LINE", "AREA", "VOLU", "NODE", "ELEM"])