openms-insight 0.1.10__tar.gz → 0.1.11__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {openms_insight-0.1.10 → openms_insight-0.1.11}/PKG-INFO +21 -1
- {openms_insight-0.1.10 → openms_insight-0.1.11}/README.md +20 -0
- {openms_insight-0.1.10 → openms_insight-0.1.11}/openms_insight/__init__.py +1 -1
- {openms_insight-0.1.10 → openms_insight-0.1.11}/openms_insight/components/heatmap.py +24 -6
- {openms_insight-0.1.10 → openms_insight-0.1.11}/openms_insight/components/table.py +12 -1
- {openms_insight-0.1.10 → openms_insight-0.1.11}/openms_insight/js-component/dist/assets/index.css +1 -1
- {openms_insight-0.1.10 → openms_insight-0.1.11}/openms_insight/js-component/dist/assets/index.js +3 -3
- {openms_insight-0.1.10 → openms_insight-0.1.11}/openms_insight/preprocessing/compression.py +9 -4
- {openms_insight-0.1.10 → openms_insight-0.1.11}/openms_insight/rendering/bridge.py +31 -9
- {openms_insight-0.1.10 → openms_insight-0.1.11}/pyproject.toml +1 -1
- {openms_insight-0.1.10 → openms_insight-0.1.11}/.gitignore +0 -0
- {openms_insight-0.1.10 → openms_insight-0.1.11}/LICENSE +0 -0
- {openms_insight-0.1.10 → openms_insight-0.1.11}/openms_insight/components/__init__.py +0 -0
- {openms_insight-0.1.10 → openms_insight-0.1.11}/openms_insight/components/lineplot.py +0 -0
- {openms_insight-0.1.10 → openms_insight-0.1.11}/openms_insight/components/sequenceview.py +0 -0
- {openms_insight-0.1.10 → openms_insight-0.1.11}/openms_insight/components/volcanoplot.py +0 -0
- {openms_insight-0.1.10 → openms_insight-0.1.11}/openms_insight/core/__init__.py +0 -0
- {openms_insight-0.1.10 → openms_insight-0.1.11}/openms_insight/core/base.py +0 -0
- {openms_insight-0.1.10 → openms_insight-0.1.11}/openms_insight/core/cache.py +0 -0
- {openms_insight-0.1.10 → openms_insight-0.1.11}/openms_insight/core/registry.py +0 -0
- {openms_insight-0.1.10 → openms_insight-0.1.11}/openms_insight/core/state.py +0 -0
- {openms_insight-0.1.10 → openms_insight-0.1.11}/openms_insight/core/subprocess_preprocess.py +0 -0
- {openms_insight-0.1.10 → openms_insight-0.1.11}/openms_insight/js-component/dist/assets/materialdesignicons-webfont.eot +0 -0
- {openms_insight-0.1.10 → openms_insight-0.1.11}/openms_insight/js-component/dist/assets/materialdesignicons-webfont.ttf +0 -0
- {openms_insight-0.1.10 → openms_insight-0.1.11}/openms_insight/js-component/dist/assets/materialdesignicons-webfont.woff +0 -0
- {openms_insight-0.1.10 → openms_insight-0.1.11}/openms_insight/js-component/dist/assets/materialdesignicons-webfont.woff2 +0 -0
- {openms_insight-0.1.10 → openms_insight-0.1.11}/openms_insight/js-component/dist/index.html +0 -0
- {openms_insight-0.1.10 → openms_insight-0.1.11}/openms_insight/preprocessing/__init__.py +0 -0
- {openms_insight-0.1.10 → openms_insight-0.1.11}/openms_insight/preprocessing/filtering.py +0 -0
- {openms_insight-0.1.10 → openms_insight-0.1.11}/openms_insight/preprocessing/scatter.py +0 -0
- {openms_insight-0.1.10 → openms_insight-0.1.11}/openms_insight/rendering/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openms-insight
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.11
|
|
4
4
|
Summary: Interactive visualization components for mass spectrometry data in Streamlit
|
|
5
5
|
Project-URL: Homepage, https://github.com/t0mdavid-m/OpenMS-Insight
|
|
6
6
|
Project-URL: Documentation, https://github.com/t0mdavid-m/OpenMS-Insight#readme
|
|
@@ -243,7 +243,9 @@ Heatmap(
|
|
|
243
243
|
- `min_points`: Target size for downsampling (default: 20000)
|
|
244
244
|
- `x_bins`, `y_bins`: Grid resolution for spatial binning
|
|
245
245
|
- `colorscale`: Plotly colorscale name (default: 'Portland')
|
|
246
|
+
- `reversescale`: Invert colorscale direction (default: False)
|
|
246
247
|
- `log_scale`: Use log10 color mapping (default: True). Set to False for linear.
|
|
248
|
+
- `low_values_on_top`: Prioritize low values during downsampling and display them on top (default: False). Use for scores where lower = better (e.g., e-values, PEP, q-values).
|
|
247
249
|
- `intensity_label`: Custom colorbar label (default: 'Intensity')
|
|
248
250
|
|
|
249
251
|
**Linear scale example:**
|
|
@@ -260,6 +262,24 @@ Heatmap(
|
|
|
260
262
|
)
|
|
261
263
|
```
|
|
262
264
|
|
|
265
|
+
**Low values on top (PSM scores):**
|
|
266
|
+
For identification results where lower scores indicate better matches (e.g., e-values, PEP, q-values), use `low_values_on_top=True` to preserve low-scoring points during downsampling and display them on top of high-scoring points:
|
|
267
|
+
|
|
268
|
+
```python
|
|
269
|
+
Heatmap(
|
|
270
|
+
cache_id="psm_evalue",
|
|
271
|
+
data_path="psm_data.parquet",
|
|
272
|
+
x_column='rt',
|
|
273
|
+
y_column='mz',
|
|
274
|
+
intensity_column='e_value',
|
|
275
|
+
log_scale=True, # Log scale for e-values
|
|
276
|
+
low_values_on_top=True, # Keep/show low e-values (best hits)
|
|
277
|
+
reversescale=True, # Bright color = low value = best
|
|
278
|
+
intensity_label='E-value',
|
|
279
|
+
colorscale='Portland',
|
|
280
|
+
)
|
|
281
|
+
```
|
|
282
|
+
|
|
263
283
|
**Categorical mode:**
|
|
264
284
|
Use `category_column` for discrete coloring by category instead of continuous intensity colorscale:
|
|
265
285
|
|
|
@@ -208,7 +208,9 @@ Heatmap(
|
|
|
208
208
|
- `min_points`: Target size for downsampling (default: 20000)
|
|
209
209
|
- `x_bins`, `y_bins`: Grid resolution for spatial binning
|
|
210
210
|
- `colorscale`: Plotly colorscale name (default: 'Portland')
|
|
211
|
+
- `reversescale`: Invert colorscale direction (default: False)
|
|
211
212
|
- `log_scale`: Use log10 color mapping (default: True). Set to False for linear.
|
|
213
|
+
- `low_values_on_top`: Prioritize low values during downsampling and display them on top (default: False). Use for scores where lower = better (e.g., e-values, PEP, q-values).
|
|
212
214
|
- `intensity_label`: Custom colorbar label (default: 'Intensity')
|
|
213
215
|
|
|
214
216
|
**Linear scale example:**
|
|
@@ -225,6 +227,24 @@ Heatmap(
|
|
|
225
227
|
)
|
|
226
228
|
```
|
|
227
229
|
|
|
230
|
+
**Low values on top (PSM scores):**
|
|
231
|
+
For identification results where lower scores indicate better matches (e.g., e-values, PEP, q-values), use `low_values_on_top=True` to preserve low-scoring points during downsampling and display them on top of high-scoring points:
|
|
232
|
+
|
|
233
|
+
```python
|
|
234
|
+
Heatmap(
|
|
235
|
+
cache_id="psm_evalue",
|
|
236
|
+
data_path="psm_data.parquet",
|
|
237
|
+
x_column='rt',
|
|
238
|
+
y_column='mz',
|
|
239
|
+
intensity_column='e_value',
|
|
240
|
+
log_scale=True, # Log scale for e-values
|
|
241
|
+
low_values_on_top=True, # Keep/show low e-values (best hits)
|
|
242
|
+
reversescale=True, # Bright color = low value = best
|
|
243
|
+
intensity_label='E-value',
|
|
244
|
+
colorscale='Portland',
|
|
245
|
+
)
|
|
246
|
+
```
|
|
247
|
+
|
|
228
248
|
**Categorical mode:**
|
|
229
249
|
Use `category_column` for discrete coloring by category instead of continuous intensity colorscale:
|
|
230
250
|
|
|
@@ -16,7 +16,7 @@ from .core.registry import get_component_class, register_component
|
|
|
16
16
|
from .core.state import StateManager
|
|
17
17
|
from .rendering.bridge import clear_component_annotations, get_component_annotations
|
|
18
18
|
|
|
19
|
-
__version__ = "0.1.
|
|
19
|
+
__version__ = "0.1.11"
|
|
20
20
|
|
|
21
21
|
__all__ = [
|
|
22
22
|
# Core
|
|
@@ -93,6 +93,7 @@ class Heatmap(BaseComponent):
|
|
|
93
93
|
category_column: Optional[str] = None,
|
|
94
94
|
category_colors: Optional[Dict[str, str]] = None,
|
|
95
95
|
log_scale: bool = True,
|
|
96
|
+
low_values_on_top: bool = False,
|
|
96
97
|
intensity_label: Optional[str] = None,
|
|
97
98
|
**kwargs,
|
|
98
99
|
):
|
|
@@ -148,6 +149,11 @@ class Heatmap(BaseComponent):
|
|
|
148
149
|
If not provided, default Plotly colors will be used.
|
|
149
150
|
log_scale: If True (default), apply log10 transformation to intensity
|
|
150
151
|
values for color mapping. Set to False for linear color mapping.
|
|
152
|
+
low_values_on_top: If True, invert the intensity priority for both downsampling
|
|
153
|
+
and display order. Default False keeps high-intensity points during
|
|
154
|
+
downsampling and draws them on top. Set to True when lower values are
|
|
155
|
+
"better" (e.g., e-values, PEP scores, q-values) so that low values are
|
|
156
|
+
preserved during downsampling and appear on top of high values.
|
|
151
157
|
intensity_label: Custom label for the colorbar. Default is "Intensity".
|
|
152
158
|
Useful when displaying non-intensity values like scores or counts.
|
|
153
159
|
**kwargs: Additional configuration options
|
|
@@ -169,6 +175,7 @@ class Heatmap(BaseComponent):
|
|
|
169
175
|
self._category_column = category_column
|
|
170
176
|
self._category_colors = category_colors or {}
|
|
171
177
|
self._log_scale = log_scale
|
|
178
|
+
self._low_values_on_top = low_values_on_top
|
|
172
179
|
self._intensity_label = intensity_label
|
|
173
180
|
self._use_streaming = use_streaming
|
|
174
181
|
self._categorical_filters = categorical_filters or []
|
|
@@ -228,6 +235,7 @@ class Heatmap(BaseComponent):
|
|
|
228
235
|
"colorscale": self._colorscale,
|
|
229
236
|
"category_column": self._category_column,
|
|
230
237
|
"log_scale": self._log_scale,
|
|
238
|
+
"low_values_on_top": self._low_values_on_top,
|
|
231
239
|
"intensity_label": self._intensity_label,
|
|
232
240
|
# Note: category_colors is render-time styling, doesn't affect cache
|
|
233
241
|
}
|
|
@@ -253,6 +261,7 @@ class Heatmap(BaseComponent):
|
|
|
253
261
|
self._colorscale = config.get("colorscale", "Portland")
|
|
254
262
|
self._category_column = config.get("category_column")
|
|
255
263
|
self._log_scale = config.get("log_scale", True)
|
|
264
|
+
self._low_values_on_top = config.get("low_values_on_top", False)
|
|
256
265
|
self._intensity_label = config.get("intensity_label")
|
|
257
266
|
# category_colors is not stored in cache (render-time styling)
|
|
258
267
|
|
|
@@ -352,6 +361,7 @@ class Heatmap(BaseComponent):
|
|
|
352
361
|
current_source,
|
|
353
362
|
max_points=target_size,
|
|
354
363
|
intensity_column=self._intensity_column,
|
|
364
|
+
descending=not self._low_values_on_top,
|
|
355
365
|
)
|
|
356
366
|
else:
|
|
357
367
|
level = downsample_2d_streaming(
|
|
@@ -364,6 +374,7 @@ class Heatmap(BaseComponent):
|
|
|
364
374
|
y_bins=self._y_bins,
|
|
365
375
|
x_range=x_range,
|
|
366
376
|
y_range=y_range,
|
|
377
|
+
descending=not self._low_values_on_top,
|
|
367
378
|
)
|
|
368
379
|
|
|
369
380
|
# Sort and save immediately
|
|
@@ -1028,25 +1039,29 @@ class Heatmap(BaseComponent):
|
|
|
1028
1039
|
columns=columns_to_select,
|
|
1029
1040
|
filter_defaults=self._filter_defaults,
|
|
1030
1041
|
)
|
|
1031
|
-
# Sort
|
|
1042
|
+
# Sort for render order (last drawn = on top in scattergl)
|
|
1043
|
+
# Default: ascending (high on top). low_values_on_top: descending (low on top)
|
|
1032
1044
|
if (
|
|
1033
1045
|
self._intensity_column
|
|
1034
1046
|
and self._intensity_column in df_pandas.columns
|
|
1035
1047
|
):
|
|
1036
1048
|
df_pandas = df_pandas.sort_values(
|
|
1037
|
-
self._intensity_column, ascending=
|
|
1049
|
+
self._intensity_column, ascending=not self._low_values_on_top
|
|
1038
1050
|
).reset_index(drop=True)
|
|
1039
1051
|
else:
|
|
1040
1052
|
# No filters to apply - levels already filtered by categorical filter
|
|
1041
1053
|
schema_names = data.collect_schema().names()
|
|
1042
1054
|
available_cols = [c for c in columns_to_select if c in schema_names]
|
|
1043
1055
|
df_polars = data.select(available_cols).collect()
|
|
1044
|
-
# Sort
|
|
1056
|
+
# Sort for render order (last drawn = on top in scattergl)
|
|
1057
|
+
# Default: ascending (high on top). low_values_on_top: descending (low on top)
|
|
1045
1058
|
if (
|
|
1046
1059
|
self._intensity_column
|
|
1047
1060
|
and self._intensity_column in df_polars.columns
|
|
1048
1061
|
):
|
|
1049
|
-
df_polars = df_polars.sort(
|
|
1062
|
+
df_polars = df_polars.sort(
|
|
1063
|
+
self._intensity_column, descending=self._low_values_on_top
|
|
1064
|
+
)
|
|
1050
1065
|
data_hash = compute_dataframe_hash(df_polars)
|
|
1051
1066
|
df_pandas = df_polars.to_pandas()
|
|
1052
1067
|
else:
|
|
@@ -1058,9 +1073,12 @@ class Heatmap(BaseComponent):
|
|
|
1058
1073
|
# Select only needed columns
|
|
1059
1074
|
available_cols = [c for c in columns_to_select if c in df_polars.columns]
|
|
1060
1075
|
df_polars = df_polars.select(available_cols)
|
|
1061
|
-
# Sort
|
|
1076
|
+
# Sort for render order (last drawn = on top in scattergl)
|
|
1077
|
+
# Default: ascending (high on top). low_values_on_top: descending (low on top)
|
|
1062
1078
|
if self._intensity_column and self._intensity_column in df_polars.columns:
|
|
1063
|
-
df_polars = df_polars.sort(
|
|
1079
|
+
df_polars = df_polars.sort(
|
|
1080
|
+
self._intensity_column, descending=self._low_values_on_top
|
|
1081
|
+
)
|
|
1064
1082
|
print(
|
|
1065
1083
|
f"[HEATMAP] Selected {len(df_polars)} pts for zoom, levels={level_sizes}",
|
|
1066
1084
|
file=sys.stderr,
|
|
@@ -650,8 +650,19 @@ class Table(BaseComponent):
|
|
|
650
650
|
|
|
651
651
|
# Apply server-side sort
|
|
652
652
|
if sort_column:
|
|
653
|
+
# User-applied sort from pagination state takes precedence
|
|
653
654
|
descending = sort_dir == "desc"
|
|
654
|
-
data = data.sort(sort_column, descending=descending)
|
|
655
|
+
data = data.sort(sort_column, descending=descending, maintain_order=True)
|
|
656
|
+
elif self._initial_sort:
|
|
657
|
+
# Fall back to initial_sort configuration on initial load
|
|
658
|
+
# initial_sort is a list of dicts: [{"column": "mass", "dir": "desc"}, ...]
|
|
659
|
+
sort_columns = [s["column"] for s in self._initial_sort]
|
|
660
|
+
sort_descending = [
|
|
661
|
+
s.get("dir", "asc") == "desc" for s in self._initial_sort
|
|
662
|
+
]
|
|
663
|
+
data = data.sort(
|
|
664
|
+
sort_columns, descending=sort_descending, maintain_order=True
|
|
665
|
+
)
|
|
655
666
|
|
|
656
667
|
# Get total row count (after filters, before pagination)
|
|
657
668
|
total_rows = data.select(pl.len()).collect().item()
|