Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
__init__.py
1"""
2Shamrock plot utility functions.
3"""
4
5import glob
6
7import shamrock.sys
8
9__all__ = []
10
11try:
12 import matplotlib.pyplot as plt
13 from matplotlib import animation
14
15 _HAS_MATPLOTLIB = True
16except ImportError:
17 _HAS_MATPLOTLIB = False
18 # print("Warning: matplotlib is not installed, some Shamrock functions will not be available")
19
20try:
21 from PIL import Image
22
23 _HAS_PIL = True
24except ImportError:
25 _HAS_PIL = False
26 # print("Warning: PIL is not installed, some Shamrock functions will not be available")
27
28try:
29 import graphviz
30
31 _HAS_GRAPHVIZ = True
32except ImportError:
33 _HAS_GRAPHVIZ = False
34 # print("Warning: graphviz is not installed, some Shamrock functions will not be available")
35
36if _HAS_MATPLOTLIB:
37 from .benchmark import add_end_labels, make_std_bench_plot
38
39 __all__.extend(["add_end_labels", "make_std_bench_plot"])
40
41if _HAS_MATPLOTLIB and _HAS_PIL:
42 __all__.append("show_image_sequence")
43
45 glob_str, render_gif=True, dpi=200, interval=50, repeat_delay=10, fig=None
46 ):
47 """
48 Create a matplotlib animation from a sequence of image files.
49
50 Available only if matplotlib and PIL are installed.
51
52 Parameters
53 ----------
54 glob_str : str
55 Glob pattern matching image files.
56 render_gif : bool, optional
57 Whether to render the animation.
58 dpi : int, optional
59 Dots per inch for the figure.
60 interval : int, optional
61 Delay between frames in milliseconds.
62 repeat_delay : int, optional
63 Delay before repeating the animation.
64
65 Raises
66 ------
67 FileNotFoundError : if no images are found for the glob pattern
68
69 Returns
70 -------
71 matplotlib.animation.FuncAnimation or None
72 Animation object on rank 0, otherwise None.
73 """
74
75 if not render_gif:
76 return None
77
78 if shamrock.sys.world_rank() != 0:
79 return None
80
81 files = sorted(glob.glob(glob_str))
82
83 image_array = []
84 for my_file in files:
85 with Image.open(my_file) as image:
86 image_array.append(image.copy())
87
88 if not image_array:
89 raise FileNotFoundError(f"No images found for glob pattern: {glob_str}")
90
91 pixel_x, pixel_y = image_array[0].size
92
93 if fig is None:
94 fig = plt.figure(dpi=dpi)
95 plt.gca().set_position((0, 0, 1, 1))
96 plt.gcf().set_size_inches(pixel_x / dpi, pixel_y / dpi)
97 plt.axis("off")
98
99 im = plt.imshow(image_array[0], animated=True, aspect="auto")
100
101 def update(i):
102 im.set_array(image_array[i])
103 return (im,)
104
105 ani = animation.FuncAnimation(
106 fig,
107 update,
108 frames=len(image_array),
109 interval=interval,
110 blit=True,
111 repeat_delay=repeat_delay,
112 )
113
114 return ani
115
116
117__all__.append("DotGraph")
118
119
121 """
122 Wrap a Graphviz DOT graph source so it renders as inline SVG.
123
124 Meant to display the solver graphs produced by e.g.
125 ``model.get_solver_dot_graph()`` or ``setup_node.get_dot()`` in the
126 sphinx-gallery generated examples: sphinx-gallery captures the
127 ``_repr_html_`` of an expression left bare as the last statement of a
128 code block (the same mechanism Jupyter uses for rich display), so no
129 custom scraper is needed. See https://stackoverflow.com/a/65117672 for
130 the technique this is based on.
131
132 ``_repr_html_`` is only defined if the graphviz python package (and the
133 Graphviz ``dot`` executable) are installed; otherwise this falls back to
134 ``__repr__``, i.e. the raw DOT source.
135
136 Parameters
137 ----------
138 dot_source : str
139 Source of the graph in the DOT language.
140 """
141
142 def __init__(self, dot_source):
143 self.dot_source = dot_source
144
145 def _repr_html_(self):
146 source = self.dot_source
147 if not source.lstrip().startswith("digraph"):
148 source = "digraph G {\n" + source + "\n}"
149 return graphviz.Source(source).pipe(format="svg").decode("utf-8")
150
151 def __repr__(self):
152 return self.dot_source
153
154
155if not _HAS_GRAPHVIZ:
156 del DotGraph._repr_html_
show_image_sequence(glob_str, render_gif=True, dpi=200, interval=50, repeat_delay=10, fig=None)
Definition __init__.py:46