Coder Social home page Coder Social logo

kitware / ipyvtklink Goto Github PK

View Code? Open in Web Editor NEW
87.0 10.0 13.0 18.99 MB

๐Ÿ”— minimalist ipywidget to interface with any Python vtkRenderWindow

License: Other

Dockerfile 6.65% Jupyter Notebook 25.80% Python 66.72% Shell 0.83%
vtk ipywidgets 3d plotting jupyter paraview pyvista python

ipyvtklink's Introduction

ipyvtklink

Binder PyPI conda

An ipywidget for vtkRenderWindow (formerly ipyvtk-simple)

This is an early prototype of creating a Jupyter interface to VTK. This toolkit is a proof of concept and a more polished tool will be available as ipyvtk in the future.

The code here was implemented from the work done by Andras Lasso under an MIT License (see the source).

The goal is to enable this widget to work with any server side vtkRenderWindow This render window could be from VTK Python, ParaView, or PyVista.

Please note that vtk is not listed as a requirement for this package to simplify its installation in virtual environments where VTK may be built from source or bundled with ParaView and we do not want to install the wheels from PyPI.

Installation

For use with PyVista, simply install with pip or conda:

pip install ipyvtklink

or

conda install -c conda-forge ipyvtklink

Run in Docker

A Docker image is prebuilt and hosted in the ipyvtklink repository's packages.

To run in Docker:

docker pull ghcr.io/kitware/ipyvtklink:latest
docker run -p 8888:8888 ghcr.io/kitware/ipyvtklink:latest

and open the vtk.ipynb notebook.

Additionally, this can be used with ParaView. An example is given in paraview.ipynb which can be run via:

docker pull ghcr.io/kitware/ipyvtklink-paraview:latest
docker run -p 8878:8878 ghcr.io/kitware/ipyvtklink-paraview:latest

Examples

You may have to build jupyter lab extensions for this to work in Lab. This is known to work well in Notebook.

PyVista

PyVista has fully implemented downstream support for ipyvtklink. See PyVista's Documentation

See the pyvista.ipynb for an original proof of concept.

demo-1

demo-2

Python VTK

The widget here can be used with VTK. Here is a minimal example showing how to pass any vtkRenderWindow to the ViewInteractiveWidget:

import vtk
from ipyvtklink.viewer import ViewInteractiveWidget

# Create some data
cylinder = vtk.vtkCylinderSource()
cylinder.SetResolution(8)
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputConnection(cylinder.GetOutputPort())
actor = vtk.vtkActor()
actor.SetMapper(mapper)

# Set up render window
ren = vtk.vtkRenderer()
ren_win = vtk.vtkRenderWindow()
ren_win.SetOffScreenRendering(1)
ren_win.SetSize(600, 600)
ren_win.AddRenderer(ren)
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(ren_win)
style = vtk.vtkInteractorStyleTrackballCamera()
iren.SetInteractorStyle(style)

# Add actor to scene
ren.AddActor(actor)
ren.ResetCamera()

# Display
ViewInteractiveWidget(ren_win)

demo-3

ParaView Python

See instructions above for running ParaView in a Docker container.

import paraview.simple as pvs
from ipyvtklink.viewer import ViewInteractiveWidget

# Create data on the pipeline
wavelet = pvs.Wavelet()
contour = pvs.Contour(Input=wavelet)
contour.ContourBy = ['POINTS', 'RTData']
contour.Isosurfaces = [63, 143, 170, 197, 276]

# Set the data as visible
pvs.Show(contour)

# Fetch the view and render the scene
view = pvs.GetActiveView()
pvs.Render(view)

# Fetch the RenderWindow
ren_win = view.GetClientSideObject().GetRenderWindow()
# Display the RenderWindow with the widget
ViewInteractiveWidget(ren_win)

demo-4

ipyvtklink's People

Contributors

akaszynski avatar banesullivan avatar denphi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ipyvtklink's Issues

Widget unusable slow when using on VSCode with Remote-SSH Plugin

Hello,

I am running VSCode and use pyvista with the ipyvtk backend to open an interactive widget showing a sphere.
It works fine, if I work in a local project. But when trying to use a project lying on a remote server using the Remote-SSH plugin, the widget becomes unusable laggy. It works fine, when starting a jupyter kernel on the remote host and connecting to it from a local VSCode project though.

This is the code I am using to create the widget:

import pyvista as pv
pv.start_xvfb() #if X11 DISPLAY is available on the server you may remove this line
sphere = pv.Sphere()
plotter = pv.Plotter(notebook=True)
plotter.add_mesh(sphere)
plotter.show(use_ipyvtk=True)

I also created an issue on vscode microsoft/vscode#121519 with a more detailed explanation.

Repo and project re-naming to reflect project's true scope / focus.

As discussed during the scientific-web (itk.js/vtk.js/girder/paraview) meeting, we wanted to invite community discussion for naming this repo / project.

It has been suggested that the focus on vtkRenderWindow should be carried in the name. For example, "vtkRenderWindowPython"

Another possibility is to continue the naming convention started with itkWidgets. For example, "vtkWidgets".

Otherwise, its focus on jupyter could be made explicit. "vtkJupyterRenderWindow"

Other ideas? Comments? Concerns?

weakref looses ren_win

Hi @banesullivan,

First, Thank you for this nice extension. It will be really useful for us.

I try to run the code below in a Jupyter notebook and I lose the interaction. As you can see, I just copied your example and move the rendering part in a function.

Do you have any idea of what's going on? what do we lose communication? Thank you for your feedback

# Create some data
cylinder = vtk.vtkCylinderSource()
cylinder.SetResolution(8)
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputConnection(cylinder.GetOutputPort())
actor = vtk.vtkActor()
actor.SetMapper(mapper)

def show(act):
    # Set up render window
    ren = vtk.vtkRenderer()
    ren_win = vtk.vtkRenderWindow()
    ren_win.SetOffScreenRendering(1)
    ren_win.SetSize(600, 600)
    ren_win.AddRenderer(ren)
    iren = vtk.vtkRenderWindowInteractor()
    iren.SetRenderWindow(ren_win)
    style = vtk.vtkInteractorStyleTrackballCamera()
    iren.SetInteractorStyle(style)

    # Add actor to scene
    ren.AddActor(act)
    ren.ResetCamera()

    # Display
    return ViewInteractiveWidget(ren_win)

show(actor)

How to make the plot update (without clicking)?

Thanks for providing this very cool package. I have been playing around with it a lot this weekend!

I am trying to create an interactive plot using pyvista and then update it from another cell. I find that my plot does not update until I click on the plot output

A simple example...

import pyvista as pv
from pyvista import examples
import ipywidgets as widgets
pv.rcParams['use_ipyvtk'] = True

mesh = examples.load_hexbeam()
p = pv.Plotter()
p.add_mesh(mesh, show_edges=True)
p.show()

Then from a different cell, I move the camera

bcpos = [(6.20, 3.00, 7.50),
         (0.16, 0.13, 2.65),
         (-0.28, 0.94, -0.21)]
p.camera_position = bcpos

Nothing happens until I actually click the plot. (I tried adding p.update(), but it had no effect.)

Screen.Recording.2021-04-11.at.3.35.30.PM.mov

This may seem like a small issue, but it really limits the ability to control the plot interactively. Is there a simple solution?

  • Python 3.8.8
  • Notebook Server 6.3.0 (not using lab)
  • pyvista 0.29.0
  • ipyvtk-simple 0.1.4

Fix canvas widget sizing issue

The widget image should be able to dynamically resize with the browser width and map to the render window. Currently, this isn't working and the image is a fixed width:

2020-07-01 09 44 53

Kernel dies when using ViewInteractiveWidget

Kernel Keeps dying when I try to use ViewInteractiveWidget(). Are there some issues with my packages? I can't seem to get it working with any combination of vtk, ipyvtklink, ipywidgets

`Package Version


anyio 4.2.0
argon2-cffi 23.1.0
argon2-cffi-bindings 21.2.0
arrow 1.3.0
asttokens 2.4.1
async-lru 2.0.4
attrs 23.2.0
Babel 2.14.0
backcall 0.2.0
beautifulsoup4 4.8.2
bleach 6.1.0
blessed 1.20.0
bpython 0.24
certifi 2019.11.28
cffi 1.16.0
chardet 3.0.4
charset-normalizer 3.3.2
click 8.1.7
comm 0.2.1
curtsies 0.4.2
cwcwidth 0.1.9
cycler 0.12.1
dbus-python 1.2.16
debugpy 1.8.0
decorator 5.1.1
defusedxml 0.7.1
distro-info 0.23+ubuntu1.1
erdantic 0.5.1
exceptiongroup 1.2.0
executing 2.0.1
fastjsonschema 2.19.1
fqdn 1.5.1
graphviz 0.20.1
greenlet 3.0.3
html5lib 1.0.1
idna 2.8
importlib-metadata 7.0.1
importlib-resources 6.1.1
iniconfig 2.0.0
ipycanvas 0.13.1
ipyevents 2.0.2
ipykernel 6.29.0
ipympl 0.8.8
ipython 8.12.3
ipython-genutils 0.2.0
ipyvtklink 0.2.3
ipywidgets 7.7.2
isoduration 20.11.0
jedi 0.19.1
Jinja2 3.1.3
json5 0.9.14
jsonpointer 2.4
jsonschema 4.21.1
jsonschema-specifications 2023.12.1
jupyter_client 8.6.0
jupyter_core 5.7.1
jupyter-events 0.9.0
jupyter-lsp 2.2.2
jupyter_server 2.12.5
jupyter_server_terminals 0.5.1
jupyterlab 4.0.11
jupyterlab_pygments 0.3.0
jupyterlab_server 2.25.2
jupyterlab-widgets 1.1.7
kiwisolver 1.4.5
lxml 4.5.0
Markdown 3.5.2
markdown-it-py 3.0.0
MarkupSafe 2.1.3
matplotlib 3.3.3
matplotlib-inline 0.1.6
mdurl 0.1.2
mistune 3.0.2
nbclient 0.9.0
nbconvert 7.14.2
nbformat 5.9.2
nest-asyncio 1.5.9
notebook 7.0.7
notebook_shim 0.2.3
numpy 1.19.5
orjson 3.9.12
overrides 7.4.0
packaging 23.2
pandas 1.2.0
pandocfilters 1.5.1
parso 0.8.3
pexpect 4.9.0
pickleshare 0.7.5
pillow 10.2.0
pip 24.0
pkgutil_resolve_name 1.3.10
platformdirs 4.1.0
plotly 4.14.3
pluggy 1.3.0
prometheus-client 0.19.0
prompt-toolkit 3.0.43
psutil 5.9.8
ptyprocess 0.7.0
pure-eval 0.2.2
pycparser 2.21
pydantic 1.10.14
pydantic_core 2.12.0
Pygments 2.17.2
PyGObject 3.36.0
pygraphviz 1.11
pyparsing 3.1.1
pyqtconsole 1.2.3
pyqtgraph 0.12.3
pytest 7.4.4
python-apt 2.0.1+ubuntu0.20.4.1
python-dateutil 2.8.2
python-json-logger 2.0.7
pytz 2023.3.post1
pyxdg 0.28
PyYAML 5.3.1
pyzmq 25.1.2
QtPy 2.4.1
qtwidgets 1.1
referencing 0.32.1
requests 2.31.0
requests-unixsocket 0.2.0
retrying 1.3.4
rfc3339-validator 0.1.4
rfc3986-validator 0.1.1
rich 13.7.0
rpds-py 0.17.1
scipy 1.6.0
Send2Trash 1.8.2
setuptools 45.2.0
six 1.14.0
sniffio 1.3.0
soupsieve 1.9.5
SQLAlchemy 1.3.22
stack-data 0.6.3
termcolor 1.1.0
terminado 0.18.0
tinycss2 1.2.1
tomli 2.0.1
tornado 6.4
tqdm 4.66.1
traitlets 5.14.1
typer 0.9.0
types-python-dateutil 2.8.19.20240106
typing_extensions 4.9.0
unattended-upgrades 0.1
uri-template 1.3.0
urllib3 1.25.8
vtk 9.3.0
wcwidth 0.2.13
webcolors 1.13
webencodings 0.5.1
websocket-client 1.7.0
wheel 0.34.2
widgetsnbextension 3.6.6
zipp 3.17.0`

How to get the correct event position when object_fit='contain'?

In mne-python, we rely on ipywidgets and ipyvtklink to design apps for MEG and EEG processing and visualization.

AFAIK, ipyvtklink uses ipyevents to get the mouse event locations. Then it does a little bit of offset computation to adjust the given coordinates from the canvas size (which depends on the notebook) to the render window size (which is fixed by the Renderer at init), correct?

Well, in our last application, we embed the ViewInteractiveWidget in a HBox for a new design:

output.mp4

What happens when all the group boxes are folded, the values given by ipyevents for boundingRectHeight and boundingRectTop used for offset calculation are correct because the image and its bounding box have the same size.

But we use viewer.layout.object_fit='contain' to preserve the aspect ratio and when the group boxes are unfolded, the bounding box of the image is stretched with the accordion and now, I think the sizes sent by ipyevents do not match anymore.

This is a problem for us because we need the correct position of the event for picking:

output.mp4

Is there a way to update the offset calculation so that GetEventPosition() returns the correct value when object_fit='contain'?

Mouse input extremely and overly sensitive

First of all, thanks for this extension. It's the only thing that interactively works in Jupyter notebooks with vtk-based libraries for some reason...

However, unlike the examples on this github page showing live interaction in a notebook, when I run any simple pyvista example in a Jupyter notebook results in uncontrollable behaviour with the mouse. If I try to orbit the camera, it goes crazy and makes big jumps. Changing mouse sensitivity in the system settings doesn't affect that behaviour. Tested on Ubuntu 20 LTS and MacOS Mojave with Jupyter notebook.

Running the same code with pyvista outside a Jupyter notebook, there's no such issue.

Should PyVista be a hard depend?

I can't make up my mind on what to do with the iPlotter class and where it would be best to maintain that. If keeping iPlotter here, we may want to make PyVista an optional dependency and have that class as a mixin. This would simplify using this widget with ParaView where we do not want pip or conda to install a separate VTK or we don't need/want PyVista and its depends in the virtual environment at all

cc @akaszynski and @GuillaumeFavelier

Support ipywidgets >=8

This package currently requires ipywidgets <8. However, versions 8.0.0 - 8.0.2 are available.

Improve interactive performance

Performance on mybinder is very poor. We need to improve the performance and set up render timers that will prevent overloads of frames trying to stream back to the client

Example notebooks does not show widgets

The notebooks currently show:

Error displaying widget: model not found

when running docker run -p 8878:8878 ipyvtk_simple jupyter lab --port=8878 --no-browser --ip=0.0.0.0 --allow-root (using the updated Dockerfile from #26).

Default style params

It'd be nice to have a way to set the default styling of the widget. I'm thinking this might be best done through an rcParams dict. This would help avoid passing **kwargs around between libs that use this (e.g. PyVista).

An example:

...
VBox([w], layout=Layout(width='50%', border='solid'))

Screen Shot 2020-11-09 at 7 40 56 AM

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.