Coverage for src/arcade_collection/convert/convert_to_projection.py: 17%
48 statements
« prev ^ index » next coverage.py v7.1.0, created at 2024-12-09 19:07 +0000
« prev ^ index » next coverage.py v7.1.0, created at 2024-12-09 19:07 +0000
1import tarfile
3import matplotlib as mpl
4import matplotlib.pyplot as plt
5from matplotlib.patches import Rectangle
7from arcade_collection.convert.convert_to_contours import convert_to_contours
10def convert_to_projection(
11 series_key: str,
12 locations_tar: tarfile.TarFile,
13 frame: int,
14 regions: list[str],
15 box: tuple[int, int, int],
16 ds: float,
17 dt: float,
18 scale: int,
19 colors: dict[str, str],
20) -> mpl.figure.Figure:
21 """
22 Convert data to projection figure.
24 Parameters
25 ----------
26 series_key
27 Simulation series key.
28 locations_tar
29 Archive of location data.
30 frame
31 Frame number.
32 regions
33 List of regions.
34 box
35 Size of bounding box.
36 ds
37 Spatial scaling in um/voxel.
38 dt
39 Temporal scaling in hours/tick.
40 scale
41 Size of scale bar (in um).
42 colors
43 Map of region to colors.
45 Returns
46 -------
47 :
48 Projection figure.
49 """
51 fig = plt.figure(figsize=(10, 10), constrained_layout=True)
52 length, width, height = box
54 ax = fig.add_subplot()
56 ax.invert_yaxis()
57 ax.get_xaxis().set_ticks([])
58 ax.get_yaxis().set_ticks([])
59 ax.set_xlim([0, length - 1])
60 ax.set_ylim([width - 1, 0])
61 ax.set_box_aspect(1)
63 ax_horz = ax.inset_axes([0, 1.005, 1, height / width], sharex=ax)
64 ax_horz.set_ylim([0, height - 1])
65 ax_horz.get_yaxis().set_ticks([])
67 ax_vert = ax.inset_axes([1.005, 0, height / length, 1], sharey=ax)
68 ax_vert.set_xlim([0, height - 1])
69 ax_vert.get_xaxis().set_ticks([])
71 ax.set_facecolor("#000")
72 ax_horz.set_facecolor("#000")
73 ax_vert.set_facecolor("#000")
75 indices = {
76 "top": list(range(1, height)),
77 "side1": list(range(1, width)),
78 "side2": list(range(1, length)),
79 }
80 contours = convert_to_contours(series_key, locations_tar, frame, regions, box, indices)
82 for region in regions:
83 color = colors[region]
85 for region_top_contours in contours[region]["top"].values():
86 for contour in region_top_contours:
87 ax.plot(contour[:, 0], contour[:, 1], linewidth=0.5, color=color, alpha=0.5)
89 for region_side1_contours in contours[region]["side1"].values():
90 for contour in region_side1_contours:
91 ax_horz.plot(contour[:, 0], contour[:, 1], linewidth=0.5, color=color, alpha=0.5)
93 for region_side2_contours in contours[region]["side2"].values():
94 for contour in region_side2_contours:
95 ax_vert.plot(contour[:, 0], contour[:, 1], linewidth=0.5, color=color, alpha=0.5)
97 add_frame_timestamp(ax, length, width, dt, frame, "#ffffff")
98 add_frame_scalebar(ax, length, width, ds, scale, "#ffffff")
100 return fig
103def add_frame_timestamp(
104 ax: mpl.axes.Axes, length: int, width: int, dt: float, frame: int, color: str
105) -> None:
106 """
107 Add a frame timestamp to figure axes.
109 Parameters
110 ----------
111 ax
112 Axes object.
113 length
114 Length of bounding box.
115 width
116 Width of bounding box.
117 dt
118 Temporal scaling in hours/tick.
119 frame
120 Frame number.
121 color
122 Timestamp color.
123 """
125 hours, minutes = divmod(round(frame * dt, 2), 1)
126 timestamp = f"{int(hours):02d}H:{round(minutes*60):02d}M"
128 ax.text(
129 0.03 * length,
130 0.96 * width,
131 timestamp,
132 fontfamily="monospace",
133 fontsize=20,
134 color=color,
135 fontweight="bold",
136 )
139def add_frame_scalebar(
140 ax: mpl.axes.Axes, length: int, width: int, ds: float, scale: int, color: str
141) -> None:
142 """
143 Add a frame scalebar to figure axes.
145 Parameters
146 ----------
147 ax
148 Axes object.
149 length
150 Length of bounding box.
151 width
152 Width of bounding box.
153 ds
154 Spatial scaling in um/voxel.
155 scale
156 Size of scale bar (in um).
157 color
158 Scalebar color.
159 """
161 scalebar = scale / ds
163 ax.add_patch(
164 Rectangle(
165 (0.95 * length - scalebar, 0.94 * width),
166 scalebar,
167 0.01 * width,
168 snap=True,
169 color=color,
170 )
171 )
173 ax.text(
174 0.95 * length - scalebar / 2,
175 0.975 * width,
176 f"{scale} $\\mu$m",
177 fontsize=10,
178 color=color,
179 horizontalalignment="center",
180 )