Skip to content

Commit b3f93dd

Browse files
authored
Enhance visualization logic in visualize.py to handle cases with no signal data. Added checks for peak areas to determine y-range and updated plot labels accordingly. Improved y-range padding logic for better visualization consistency. (#44)
1 parent 987ffae commit b3f93dd

File tree

1 file changed

+42
-10
lines changed

1 file changed

+42
-10
lines changed

chromhandler/visualize.py

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,19 +43,43 @@ def visualize(
4343
# First pass: collect all y-values to determine global y-range
4444
y_min = float("inf")
4545
y_max = float("-inf")
46+
has_signal_data = False
47+
4648
for meas in handler.measurements:
4749
for chrom in meas.chromatograms[:1]:
4850
if chrom.signals:
4951
y_min = min(y_min, min(chrom.signals))
5052
y_max = max(y_max, max(chrom.signals))
53+
has_signal_data = True
5154
if show_processed and chrom.processed_signal:
5255
y_min = min(y_min, min(chrom.processed_signal))
5356
y_max = max(y_max, max(chrom.processed_signal))
57+
has_signal_data = True
58+
59+
# If no signal data is available, collect peak areas for y-range
60+
if not has_signal_data:
61+
for meas in handler.measurements:
62+
for chrom in meas.chromatograms[:1]:
63+
if chrom.peaks:
64+
for peak in chrom.peaks:
65+
if peak.area is not None:
66+
y_min = min(y_min, 0) # Start from 0 for peak areas
67+
y_max = max(y_max, peak.area)
68+
has_signal_data = True
69+
70+
# If still no data, set default range
71+
if not has_signal_data:
72+
y_min = 0
73+
y_max = 1
5474

5575
# Add some padding to the y-range
5676
y_range = y_max - y_min
57-
y_min = y_min - 0.05 * y_range
58-
y_max = y_max + 0.05 * y_range
77+
if y_range > 0:
78+
y_min = y_min - 0.05 * y_range
79+
y_max = y_max + 0.05 * y_range
80+
else:
81+
y_min = 0
82+
y_max = 1
5983

6084
# Collect all retention times for consistent coloring
6185
all_retention_times = []
@@ -159,15 +183,18 @@ def visualize(
159183
else:
160184
label = f"Peak {peak.retention_time:.2f}"
161185

162-
# Plot vertical line with consistent color but measurement-specific linestyle
186+
# Plot vertical line with height based on peak area
187+
peak_height = peak.area if peak.area is not None else 0
188+
163189
# Use a dashed line with increasing dash length based on measurement index
164190
linestyle = (
165191
0,
166192
(1, i + 1),
167193
) # (0, (1, 1)) for first measurement, (0, (1, 2)) for second, etc.
168194

169-
ax.axvline(
170-
x=peak.retention_time,
195+
ax.plot(
196+
[peak.retention_time, peak.retention_time],
197+
[0, peak_height],
171198
color=color,
172199
linestyle=linestyle,
173200
alpha=0.7,
@@ -177,7 +204,8 @@ def visualize(
177204
)
178205

179206
# Set plot properties
180-
ax.set_ylabel("Intensity")
207+
ylabel = "Peak Area" if not has_signal_data else "Intensity"
208+
ax.set_ylabel(ylabel)
181209
ax.set_xlabel("Retention time [min]")
182210
ax.grid(True, alpha=0.3)
183211

@@ -258,9 +286,12 @@ def visualize(
258286
else:
259287
label = f"Peak {peak.retention_time:.2f}"
260288

261-
# Plot vertical line with consistent color
262-
ax.axvline(
263-
x=peak.retention_time,
289+
# Plot vertical line with height based on peak area
290+
peak_height = peak.area if peak.area is not None else 0
291+
292+
ax.plot(
293+
[peak.retention_time, peak.retention_time],
294+
[0, peak_height],
264295
color=color,
265296
linestyle="-",
266297
alpha=0.7,
@@ -309,7 +340,8 @@ def visualize(
309340
ax.set_xlabel("")
310341

311342
if idx % n_cols == 0: # Only show y-label for leftmost plots
312-
ax.set_ylabel("Intensity")
343+
ylabel = "Peak Area" if not has_signal_data else "Intensity"
344+
ax.set_ylabel(ylabel)
313345
ax.grid(True, alpha=0.3)
314346
ax.legend(loc="upper right", fontsize=8, title="RT [min]", title_fontsize=9)
315347
ax.set_ylim(y_min, y_max) # Set consistent y-range for all plots

0 commit comments

Comments
 (0)