diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index fd02ee7..260dd88 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -59,13 +59,6 @@ jobs: EXAMPLE="examples/${{ matrix.example }}" EXAMPLE_DIR=$(dirname "${EXAMPLE}") EXAMPLE_FILE=$(basename "${EXAMPLE}") - FIGURE_DIR=$(realpath figs/) - - echo "ARTIFACT_NAME=${EXAMPLE_FILE}" >> $GITHUB_ENV - echo "FIGURE_DIR=${FIGURE_DIR}" >> $GITHUB_ENV - - mkdir -p "${FIGURE_DIR}" - python rhodium/test/plot_to_savefig.py "${EXAMPLE}" "${FIGURE_DIR}" pushd "${EXAMPLE_DIR}" @@ -73,17 +66,20 @@ jobs: make fi + IMAGES_DIR=$(realpath images/) + export RHODIUM_NO_PROMPT=true + export RHODIUM_FIGURE_OUTPUT="${IMAGES_DIR}" export LD_LIBRARY_PATH="$(pwd):${LD_LIBRARY_PATH}" + python "${EXAMPLE_FILE}" - if [ -d "images/" ]; then - mv images/ "${FIGURE_DIR}" - fi + echo "IMAGES_DIR=${IMAGES_DIR}" >> $GITHUB_ENV + echo "ARTIFACT_NAME=${EXAMPLE_FILE}" >> $GITHUB_ENV - name: Upload figures uses: actions/upload-artifact@v4 with: name: "${{ env.ARTIFACT_NAME }}" - path: "${{ env.FIGURE_DIR }}" + path: "${{ env.IMAGES_DIR }}" if-no-files-found: ignore diff --git a/rhodium/plot.py b/rhodium/plot.py index d5c4873..bf8b4f9 100644 --- a/rhodium/plot.py +++ b/rhodium/plot.py @@ -15,6 +15,7 @@ # # You should have received a copy of the GNU General Public License # along with Rhodium. If not, see . +import os import mplcursors import matplotlib as mpl import matplotlib.pyplot as plt @@ -29,6 +30,23 @@ from .model import Response from .brush import BrushSet, apply_brush, color_brush, brush_color_map, color_indices +# When set, override the plt.show() method to save. Intended for CI +# or headless mode. +_figure_output_envvar = "RHODIUM_FIGURE_OUTPUT" + +if os.getenv(_figure_output_envvar): + def show_override(*args, **kwargs): + directory = os.getenv(_figure_output_envvar) + + if not os.path.exists(directory): + os.makedirs(directory, exist_ok=True) + + filename = os.path.join(directory, f"figure_{plt.gcf().number}.png") + plt.savefig(filename) + print(f"{_figure_output_envvar} set, saving figure to {filename}") + + plt.show = show_override + def _combine_keys(*args): result = [] result_set = set() @@ -423,6 +441,7 @@ def kdeplot(model, data, x, y, cmap=["Reds", "Blues", "Oranges", "Greens", "Greys"], **kwargs): df = data.as_dataframe() + plt.figure() if brush is None: sns.kdeplot(x=df[x], diff --git a/rhodium/test/plot_to_savefig.py b/rhodium/test/plot_to_savefig.py deleted file mode 100644 index 2e47856..0000000 --- a/rhodium/test/plot_to_savefig.py +++ /dev/null @@ -1,30 +0,0 @@ -import sys -import re -import pathlib - -if __name__ == "__main__": - if len(sys.argv) != 3: - print("Usage: " + __file__ + " [file] [fig_path]") - sys.exit(-1) - - fig_index = 1 - fig_basename = pathlib.Path(sys.argv[2]) / pathlib.Path(sys.argv[1]).stem - pyplot_alias = "matplotlib.pyplot" - result = [] - - with open(sys.argv[1], "r") as f: - for line in f: - m = re.search(r"import matplotlib.pyplot as ([a-zA-Z_]+)", line) - if m: - pyplot_alias = m.group(1) - - m = re.search(pyplot_alias + r".show\(\)", line) - if m: - line = line[:m.start()] + pyplot_alias + ".savefig('" + str(fig_basename) + "." + str(fig_index) + ".png')" + line[m.end():] - fig_index += 1 - - result.append(line) - - with open(sys.argv[1], "w") as f: - for line in result: - f.write(line)