Skip to content

Commit

Permalink
initial widget works
Browse files Browse the repository at this point in the history
  • Loading branch information
chrishavlin committed Nov 21, 2024
1 parent e3c8b90 commit a7f0def
Show file tree
Hide file tree
Showing 4 changed files with 230 additions and 64 deletions.
105 changes: 105 additions & 0 deletions docs/examples/PhasePlotTempExample.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "631b90ba-e543-4078-b234-4fc7b18c8fbf",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[<Image layer 'nuclei' at 0x76b12a76d0f0>,\n",
" <Image layer 'WGA' at 0x76b12a217c70>,\n",
" <Image layer 'actin' at 0x76b12a28a9e0>]"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"yt : [INFO ] 2024-11-21 14:42:35,829 Parameters: current_time = 0.0\n",
"yt : [INFO ] 2024-11-21 14:42:35,830 Parameters: domain_dimensions = [ 16 512 512]\n",
"yt : [INFO ] 2024-11-21 14:42:35,831 Parameters: domain_left_edge = [0. 0. 0.]\n",
"yt : [INFO ] 2024-11-21 14:42:35,832 Parameters: domain_right_edge = [1. 1. 1.]\n",
"yt : [INFO ] 2024-11-21 14:42:35,832 Parameters: cosmological_simulation = 0\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"x\n",
"y\n",
"nuclei\n",
"nuclei\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"yt : [INFO ] 2024-11-21 14:43:09,699 Parameters: current_time = 0.0\n",
"yt : [INFO ] 2024-11-21 14:43:09,700 Parameters: domain_dimensions = [ 16 512 512]\n",
"yt : [INFO ] 2024-11-21 14:43:09,700 Parameters: domain_left_edge = [0. 0. 0.]\n",
"yt : [INFO ] 2024-11-21 14:43:09,701 Parameters: domain_right_edge = [1. 1. 1.]\n",
"yt : [INFO ] 2024-11-21 14:43:09,702 Parameters: cosmological_simulation = 0\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"nuclei\n",
"WGA\n",
"actin\n",
"x\n"
]
}
],
"source": [
"import napari \n",
"import yt \n",
"\n",
"v = napari.Viewer()\n",
"v.open_sample(\n",
" plugin = 'napari', \n",
" sample = 'kidney',\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2e92b80f-7ee3-4e72-9dd7-aff1a0342689",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.6"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
87 changes: 51 additions & 36 deletions docs/examples/ytnapari_to_yt.ipynb

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions src/yt_napari/_gui_utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import pydantic
from magicgui import type_map, widgets
from pydantic_core import PydanticUndefinedType
from qtpy.QtWidgets import QLayout

from yt_napari import _data_model
from yt_napari.logging import ytnapari_log
Expand Down Expand Up @@ -380,3 +381,11 @@ def get_yt_metadata_container():
def _is_base_model_or_yt_obj(field_info: pydantic.fields.FieldInfo):
ftype = field_info.annotation
return ftype in _data_model._data_model_list


def clearLayout(layout: QLayout):
# remove all widgets from a layout
while layout.count():
child = layout.takeAt(0)
if child.widget():
child.widget().deleteLater()

Check warning on line 391 in src/yt_napari/_gui_utilities.py

View check run for this annotation

Codecov / codecov/patch

src/yt_napari/_gui_utilities.py#L388-L391

Added lines #L388 - L391 were not covered by tests
93 changes: 65 additions & 28 deletions src/yt_napari/_widget_2d_plots.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import napari
import numpy as np
import yt
from magicgui import widgets
from qtpy.QtWidgets import QComboBox, QHBoxLayout, QVBoxLayout, QWidget
from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg
from qtpy.QtWidgets import QComboBox, QLabel, QVBoxLayout, QWidget

Check warning on line 5 in src/yt_napari/_widget_2d_plots.py

View check run for this annotation

Codecov / codecov/patch

src/yt_napari/_widget_2d_plots.py#L1-L5

Added lines #L1 - L5 were not covered by tests

from yt_napari._gui_utilities import clearLayout
from yt_napari.viewer import layers_to_yt

Check warning on line 8 in src/yt_napari/_widget_2d_plots.py

View check run for this annotation

Codecov / codecov/patch

src/yt_napari/_widget_2d_plots.py#L7-L8

Added lines #L7 - L8 were not covered by tests


class YTPhasePlot(QWidget):
Expand All @@ -23,21 +26,36 @@ def __init__(self, napari_viewer: "napari.viewer.Viewer", parent=None):
value=active_layers[0], choices=active_layers, name="Layer 3"
).native

self.layer_4_weight: QComboBox = widgets.ComboBox(

Check warning on line 29 in src/yt_napari/_widget_2d_plots.py

View check run for this annotation

Codecov / codecov/patch

src/yt_napari/_widget_2d_plots.py#L29

Added line #L29 was not covered by tests
value="None",
choices=[
"None",
]
+ active_layers,
name="Layer 4",
).native

self.layout().addWidget(self.layer_1)
self.layout().addWidget(self.layer_2)
self.layout().addWidget(self.layer_3)
self.layout().addWidget(self.layer_4_weight)

Check warning on line 41 in src/yt_napari/_widget_2d_plots.py

View check run for this annotation

Codecov / codecov/patch

src/yt_napari/_widget_2d_plots.py#L38-L41

Added lines #L38 - L41 were not covered by tests

update_layers = widgets.PushButton(text="Refresh layers")
update_layers.clicked.connect(self.update_available_layers)
self.update_layers = update_layers
self.layout().addWidget(self.update_layers.native)

Check warning on line 46 in src/yt_napari/_widget_2d_plots.py

View check run for this annotation

Codecov / codecov/patch

src/yt_napari/_widget_2d_plots.py#L43-L46

Added lines #L43 - L46 were not covered by tests

self.phaseplot_container = QHBoxLayout()
self.render_button = widgets.PushButton(text="Render")
self.render_button.clicked.connect(self.render_phaseplot)
self.phaseplot_container.addWidget(self.render_button.native)
self.layout().addWidget(self.render_button.native)

Check warning on line 50 in src/yt_napari/_widget_2d_plots.py

View check run for this annotation

Codecov / codecov/patch

src/yt_napari/_widget_2d_plots.py#L48-L50

Added lines #L48 - L50 were not covered by tests

self.phaseplot_container = QVBoxLayout()
self.phaseplot_container.addWidget(QLabel(text="Click render to generate plot"))
self.layout().addLayout(self.phaseplot_container)

Check warning on line 54 in src/yt_napari/_widget_2d_plots.py

View check run for this annotation

Codecov / codecov/patch

src/yt_napari/_widget_2d_plots.py#L52-L54

Added lines #L52 - L54 were not covered by tests

self.fig = None
self.canvas = None

Check warning on line 57 in src/yt_napari/_widget_2d_plots.py

View check run for this annotation

Codecov / codecov/patch

src/yt_napari/_widget_2d_plots.py#L56-L57

Added lines #L56 - L57 were not covered by tests

def update_available_layers(self):
print("update those layers")
layers = self.available_layer_list

Check warning on line 61 in src/yt_napari/_widget_2d_plots.py

View check run for this annotation

Codecov / codecov/patch

src/yt_napari/_widget_2d_plots.py#L59-L61

Added lines #L59 - L61 were not covered by tests
Expand All @@ -53,45 +71,64 @@ def update_available_layers(self):
self.layer_3.clear()
self.layer_3.addItems(layers)
self.layer_3.setCurrentIndex(0)

Check warning on line 73 in src/yt_napari/_widget_2d_plots.py

View check run for this annotation

Codecov / codecov/patch

src/yt_napari/_widget_2d_plots.py#L65-L73

Added lines #L65 - L73 were not covered by tests

# add option for weight_field
# weight field
self.layer_4.clear()
self.layer_4.addItems(

Check warning on line 76 in src/yt_napari/_widget_2d_plots.py

View check run for this annotation

Codecov / codecov/patch

src/yt_napari/_widget_2d_plots.py#L75-L76

Added lines #L75 - L76 were not covered by tests
[
"None",
]
+ layers
)
self.layer_4.setCurrentIndex(0)

Check warning on line 82 in src/yt_napari/_widget_2d_plots.py

View check run for this annotation

Codecov / codecov/patch

src/yt_napari/_widget_2d_plots.py#L82

Added line #L82 was not covered by tests

def render_phaseplot(self):

Check warning on line 84 in src/yt_napari/_widget_2d_plots.py

View check run for this annotation

Codecov / codecov/patch

src/yt_napari/_widget_2d_plots.py#L84

Added line #L84 was not covered by tests

layer1 = self.current_layers[self.layer_1.currentIndex()]
layer2 = self.current_layers[self.layer_2.currentIndex()]
layer3 = self.current_layers[self.layer_3.currentIndex()]
wt_field = self.current_layers[self.layer_4_weight.currentIndex()]
if wt_field == "None":
wt_field = None

Check warning on line 91 in src/yt_napari/_widget_2d_plots.py

View check run for this annotation

Codecov / codecov/patch

src/yt_napari/_widget_2d_plots.py#L86-L91

Added lines #L86 - L91 were not covered by tests

layers = [layer1, layer2, layer3, wt_field]
layers_for_yt = []
pp_args = []
for layer in layers:
print(layer)
if _is_index_field(layer):
pp_args.append(("index", layer))
elif layer is not None:
pp_args.append(("stream", layer))
layers_for_yt.append(layer)

Check warning on line 102 in src/yt_napari/_widget_2d_plots.py

View check run for this annotation

Codecov / codecov/patch

src/yt_napari/_widget_2d_plots.py#L93-L102

Added lines #L93 - L102 were not covered by tests
else:
pp_args.append(None)

Check warning on line 104 in src/yt_napari/_widget_2d_plots.py

View check run for this annotation

Codecov / codecov/patch

src/yt_napari/_widget_2d_plots.py#L104

Added line #L104 was not covered by tests

ds = layers_to_yt(self.viewer, layers_for_yt, axis_order=("z", "y", "x"))

Check warning on line 106 in src/yt_napari/_widget_2d_plots.py

View check run for this annotation

Codecov / codecov/patch

src/yt_napari/_widget_2d_plots.py#L106

Added line #L106 was not covered by tests

print("get those layers")

l1 = self.viewer.layers[layer1]
l2 = self.viewer.layers[layer2]
l3 = self.viewer.layers[layer3]

data = {
l1.name: l1.data,
l2.name: l2.data,
l3.name: l3.data,
}

dims = data[l1.name].shape
bbox = np.array([[0, dims[idim]] for idim in range(len(dims))])
ds = yt.load_uniform_grid(data, dims, bbox=bbox, length_unit=1)
# TODO: adjust for when selecting x, y, z
pp = yt.PhasePlot(

Check warning on line 108 in src/yt_napari/_widget_2d_plots.py

View check run for this annotation

Codecov / codecov/patch

src/yt_napari/_widget_2d_plots.py#L108

Added line #L108 was not covered by tests
ds,
("stream", l1.name),
("stream", l2.name),
("stream", l3.name),
weight_field=None,
pp_args[0],
pp_args[1],
pp_args[2],
weight_field=pp_args[3],
)
pp.render()

Check warning on line 115 in src/yt_napari/_widget_2d_plots.py

View check run for this annotation

Codecov / codecov/patch

src/yt_napari/_widget_2d_plots.py#L115

Added line #L115 was not covered by tests
print("rendered... need to put the image in the widget...")

clearLayout(self.phaseplot_container)

Check warning on line 117 in src/yt_napari/_widget_2d_plots.py

View check run for this annotation

Codecov / codecov/patch

src/yt_napari/_widget_2d_plots.py#L117

Added line #L117 was not covered by tests

self.fig = pp.plots[pp.fields[0]].figure
self.canvas = FigureCanvasQTAgg(self.fig)
self.canvas.draw()
self.phaseplot_container.addWidget(self.canvas)

Check warning on line 122 in src/yt_napari/_widget_2d_plots.py

View check run for this annotation

Codecov / codecov/patch

src/yt_napari/_widget_2d_plots.py#L119-L122

Added lines #L119 - L122 were not covered by tests

@property
def available_layer_list(self):
layers = [layer.name for layer in self.viewer.layers]

Check warning on line 126 in src/yt_napari/_widget_2d_plots.py

View check run for this annotation

Codecov / codecov/patch

src/yt_napari/_widget_2d_plots.py#L124-L126

Added lines #L124 - L126 were not covered by tests

dims = ["x", "y", "z"] # TODO: check ndim
dims = ["x", "y", "z", "ones"] # TODO: check ndim
layers += dims
return layers

Check warning on line 130 in src/yt_napari/_widget_2d_plots.py

View check run for this annotation

Codecov / codecov/patch

src/yt_napari/_widget_2d_plots.py#L128-L130

Added lines #L128 - L130 were not covered by tests


def _is_index_field(layer_name: str):
return layer_name in ("x", "y", "z", "ones")

Check warning on line 134 in src/yt_napari/_widget_2d_plots.py

View check run for this annotation

Codecov / codecov/patch

src/yt_napari/_widget_2d_plots.py#L133-L134

Added lines #L133 - L134 were not covered by tests

0 comments on commit a7f0def

Please sign in to comment.