diff --git a/doc/changelog.d/4196.added.md b/doc/changelog.d/4196.added.md new file mode 100644 index 00000000000..5f7f767741a --- /dev/null +++ b/doc/changelog.d/4196.added.md @@ -0,0 +1 @@ +Adding plvar to plot commands diff --git a/doc/changelog.d/4204.added.md b/doc/changelog.d/4204.added.md new file mode 100644 index 00000000000..731d7653d0f --- /dev/null +++ b/doc/changelog.d/4204.added.md @@ -0,0 +1 @@ +Adding PLVAR to plot commands diff --git a/examples/00-mapdl-examples/psd-vm203.py b/examples/00-mapdl-examples/psd-vm203.py index 1545b83ed6c..b6f31856f5d 100644 --- a/examples/00-mapdl-examples/psd-vm203.py +++ b/examples/00-mapdl-examples/psd-vm203.py @@ -256,17 +256,39 @@ Pmax = rpsduz.max() ############################################################################### -# plot the response psd +# You can plot the response psd using MAPDL methods: + +# Setting up the PSD plot with MAPDL +mapdl.axlab("X", "Frequency (Hz)") +mapdl.axlab("Y", "RPSD (M**2/Hz)") +mapdl.yrange(ymin="0", ymax="0.004") +mapdl.xrange(xmin="0", xmax="80") +mapdl.gropt(lab="LOGY", key="ON") + +mapdl.xvar(0) # Plot against time/frequency +mapdl.plvar(3) # Plot variable set 3 (RPSD) + +############################################################################### +# or use matplotlib: + freqs = mapdl.vget("FREQS", 1) # Remove the last two values as they are zero -plt.plot(freqs[:-2], rpsduz[:-2], label="RPSD UZ") +fig, ax = plt.subplots(figsize=(8, 4)) + +ax.plot(freqs, rpsduz, label="RPSD UZ") + +ax.set_yscale("log") +ax.set_xlabel("Frequency (Hz)") +ax.set_ylabel(r"RPSD $\left( \dfrac{M^2}{Hz}\right)$") +ax.set_xlim((0, 80)) +ax.set_ylim((0, 0.004)) +ax.grid() + +fig.legend() -plt.xlabel("Frequency Hz") -plt.ylabel(r"RPSD $\left( \dfrac{M^2}{Hz}\right)$") -plt.legend() -plt.tight_layout() -plt.show() +fig.tight_layout() +fig.show() ############################################################################### # Compare and print results to manual values diff --git a/src/ansys/mapdl/core/mapdl_core.py b/src/ansys/mapdl/core/mapdl_core.py index 320e84abed9..7650802c2ff 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. @@ -192,6 +192,7 @@ "NPLO", "PLES", "PLNS", + "PLVA", "PSDG", "SECP", "SPGR", @@ -2323,7 +2324,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 +2420,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 +2440,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 +2498,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 +2538,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 +2578,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 +3283,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 +3312,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 50c8ee0165c..555cf145f58 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 b5154fd3a5a..56ef1beb906 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 27b6f9b419a..d2e2fd5050e 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"]) @@ -1341,3 +1338,10 @@ def test_deprecated_params(mapdl, make_block): mapdl.eplot(vtk=True) with pytest.warns(DeprecationWarning, match="'vtk' and 'use_vtk' are deprecated"): mapdl.eplot(vtk=False) + + +def test_plvar(mapdl, coupled_example): + mapdl.post26() + with patch("ansys.mapdl.core.Mapdl.screenshot") as mock_screenshot: + mapdl.plvar(4, 5) + mock_screenshot.assert_called_once()