Skip to content

chore(concat): attempt to silence warning from magick #40

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

Merged
merged 2 commits into from
Dec 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,10 @@ combining the plots using the `subfigure` environment in latex or similar is not
option, this is easily done with [`imagemagick`](https://imagemagick.org/index.php) in a
systematic way.

> [!caution]
>
> This uses `imagemagick v7`.

The `Combine` class within the `concat` module implements such procedures, and is also
conveniently available from the `combine` function in `cosmoplots`.

Expand Down Expand Up @@ -196,7 +200,7 @@ plot(7)
plot(8)
plot(9)
plot(10)
# See `magick convert -list font` for all available fonts.
# See `magick -list font` for all available fonts.
figs = [f"./assets/{i}.png" for i in range(1, 11)]
cosmoplots.combine(*figs).using(
font="JetBrainsMonoNL-NFM-Medium",
Expand Down
38 changes: 24 additions & 14 deletions cosmoplots/concat.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

# `Self` was introduced in 3.11, but returning the class type works from 3.7 onwards.
from __future__ import annotations
import warnings

import logging
import pathlib
import subprocess
import tempfile
import warnings
from contextlib import contextmanager

import matplotlib.pyplot as plt
Expand Down Expand Up @@ -90,7 +90,7 @@ def using(
The position in the subfigure relative to `gravity`. Default is `(10.0,
10.0)`.
font : str, optional
The type of font to use, default is Times New Roman. See `magick convert -list
The type of font to use, default is Times New Roman. See `magick -list
font` for a list of available fonts.
fontsize : int, optional
The size of the font in pointsize. Default is to use the "font.size" field
Expand Down Expand Up @@ -194,7 +194,7 @@ def _check_params_before_save(
)
if self._ft in [".eps", ".pdf"]:
warnings.warn(
"The ImageMagick `magick convert` command does not work well with vector"
"The ImageMagick `magick` command does not work well with vector"
" formats. Consider combining the plots directly using matplotlib,"
" or change to a different format, such as 'png' or 'jpg'. See also"
" https://www.imagemagick.org/Usage/formats/#vector",
Expand All @@ -209,13 +209,22 @@ def _check_params_before_save(
@staticmethod
def _check_cli_available() -> None:
try:
subprocess.check_output("magick convert --help", shell=True)
subprocess.check_output("magick --help", shell=True)
except subprocess.CalledProcessError as e:
raise ChildProcessError(
"Calling `magick convert --help` did not work. Are you sure you have "
"Calling `magick --help` did not work. Are you sure you have "
"imagemagick installed? If not, resort to the ImageMagick website: "
"https://imagemagick.org/script/download.php"
) from e
result = subprocess.check_output(["magick", "--version"])
out = "b'Version: ImageMagick 7'"
v = str(result).split(" ")[2]
if str(result[:22]) != out:
warnings.warn(
f"WARNING: It looks like your version of ImageMagick is {v}. This class"
" assumes you are using version 7.",
stacklevel=2,
)

def _run_subprocess(self) -> None:
# In case several python runtimes use this class, we use a temporary directory
Expand All @@ -232,10 +241,9 @@ def _run_subprocess(self) -> None:
subprocess.call(
[
"magick",
"convert",
file,
"-units",
"PixelsPerInch",
file,
"-density",
str(self._dpi),
"-font",
Expand All @@ -255,15 +263,17 @@ def _run_subprocess(self) -> None:
# Choose first n items in the list
idx_sub = idx[j * self._w : (j + 1) * self._w]
subprocess.call(
["magick", "convert", "+append"]
["magick"]
+ [tmp_path / f"{str(i)}{self._ft}" for i in idx_sub]
+ [tmp_path / f"subfigure_{j}{self._ft}"]
+ ["+append"]
+ [tmp_path / f"subfigure_{j}{self._ft}"],
)

# Create vertical subfigures from horizontal subfigures
subprocess.call(
["magick", "convert", "-append"]
["magick"]
+ [tmp_path / f"subfigure_{j}{self._ft}" for j in range(self._h)]
+ ["-append"]
+ [self._output.resolve()]
)

Expand All @@ -275,7 +285,7 @@ def help(self) -> None:

def _conv_cmd(lab) -> str:
return (
f" magick convert in-{lab}{self._ft} -font {self._font} -pointsize"
f" magick in-{lab}{self._ft} -font {self._font} -pointsize"
f' {self._fontsize} -draw "gravity {self._gravity} fill {self._color}'
f" text {self._pos[0]},{self._pos[1]} '({lab})'\" {lab}{self._ft}\n"
)
Expand All @@ -287,10 +297,10 @@ def _conv_cmd(lab) -> str:
f"{_conv_cmd('c')}"
f"{_conv_cmd('d')}"
"Then to combine them horizontally:\n"
f" magick convert +append a{self._ft} b{self._ft} ab{self._ft}\n"
f" magick convert +append c{self._ft} d{self._ft} cd{self._ft}\n"
f" magick a{self._ft} b{self._ft} +append ab{self._ft}\n"
f" magick c{self._ft} d{self._ft} +append cd{self._ft}\n"
"And finally stack them vertically:\n"
f" magick convert -append ab{self._ft} cd{self._ft} out{self._ft}\n"
f" magick ab{self._ft} cd{self._ft} -append out{self._ft}\n"
"Optionally delete all temporary files:\n"
f" rm a{self._ft} b{self._ft} c{self._ft} d{self._ft} ab{self._ft} cd{self._ft}"
)
Expand Down
22 changes: 11 additions & 11 deletions tests/test_concat.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ def plot() -> None:
ax.semilogy(a)


def test_magick_convert_help() -> None:
def test_magick_version() -> None:
"""Test that ImageMagick's magick command is available."""
result = subprocess.check_output(["magick", "convert", "--help"])
out = "b'Version: ImageMagick'"
assert str(result[:20]) == out
result = subprocess.check_output(["magick", "--version"])
out = "b'Version: ImageMagick 7'"
assert str(result[:22]) == out


def test_help(capfd) -> None:
Expand All @@ -39,15 +39,15 @@ def test_help(capfd) -> None:
out, err = capfd.readouterr()
help = (
"To create images with labels:\n"
" magick convert in-a.png -font Times-New-Roman -pointsize 100 -draw \"gravity northwest fill black text 10.0,10.0 '(a)'\" a.png\n"
" magick convert in-b.png -font Times-New-Roman -pointsize 100 -draw \"gravity northwest fill black text 10.0,10.0 '(b)'\" b.png\n"
" magick convert in-c.png -font Times-New-Roman -pointsize 100 -draw \"gravity northwest fill black text 10.0,10.0 '(c)'\" c.png\n"
" magick convert in-d.png -font Times-New-Roman -pointsize 100 -draw \"gravity northwest fill black text 10.0,10.0 '(d)'\" d.png\n"
" magick in-a.png -font Times-New-Roman -pointsize 100 -draw \"gravity northwest fill black text 10.0,10.0 '(a)'\" a.png\n"
" magick in-b.png -font Times-New-Roman -pointsize 100 -draw \"gravity northwest fill black text 10.0,10.0 '(b)'\" b.png\n"
" magick in-c.png -font Times-New-Roman -pointsize 100 -draw \"gravity northwest fill black text 10.0,10.0 '(c)'\" c.png\n"
" magick in-d.png -font Times-New-Roman -pointsize 100 -draw \"gravity northwest fill black text 10.0,10.0 '(d)'\" d.png\n"
"Then to combine them horizontally:\n"
" magick convert +append a.png b.png ab.png\n"
" magick convert +append c.png d.png cd.png\n"
" magick a.png b.png +append ab.png\n"
" magick c.png d.png +append cd.png\n"
"And finally stack them vertically:\n"
" magick convert -append ab.png cd.png out.png\n"
" magick ab.png cd.png -append out.png\n"
"Optionally delete all temporary files:\n"
" rm a.png b.png c.png d.png ab.png cd.png\n"
)
Expand Down
Loading