Andreas
Andreas

Reputation: 11

PyVista plotting issue in Visual Studio Code using WSL 2 with Ubuntu 22.04.4

I am using the latest release of dolfinx-fenics (https://fenicsproject.org) on a Lenovo Think Pad with an Intel(R) Core(TM) i7-8550U CPU @1.80GHZ. It's a 64-Bit-System with Windows 11 Pro version 23H2. I have an Intel(R) UHD Graphics 620 graphic card.

On it I have installed the latest version of Visual Studio Code and connect it via WSL 2 to my Ubuntu 22.04.4 installation. The Kernel I use is the one of Ubuntu with a python 3.10.12 To run FEM calculations with fenicsx I use a ipynb notebook, but the same error occurs using a .py standard file. I have below a code snippet (I try to make it minimal working)

from mpi4py import MPI
import pyvista
from dolfinx import mesh, plot

pyvista.OFF_SCREEN = True

print(pyvista.global_theme.jupyter_backend)

domain = mesh.create_unit_square(MPI.COMM_WORLD, 8, 8, mesh.CellType.quadrilateral)
tdim = domain.topology.dim

pyvista.start_xvfb()
domain.topology.create_connectivity(tdim, tdim)
topology, cell_types, geometry = plot.vtk_mesh(domain, tdim)
grid = pyvista.UnstructuredGrid(topology, cell_types, geometry)

plotter = pyvista.Plotter()
plotter.add_mesh(grid, show_edges=True)
plotter.view_xy()
plotter.show()

The result is a black image with nothing on it. I can try to plot a function instead but the results is that I see the colorbar with the labels but nothing more.

I have already tried a number of things.

  1. Turning pyvista.OFF_SCREEN = True did not resolve the issue.
  2. Updating all the dependencies and packages did also not help.
  3. I also downloaded VcXsrv and added it to my bash script without success.
  4. Switching the backend to static to plot with Matplotlib worked until I restarted the kernel.
  5. Disapling anti aliasing plotter.disable_anti_aliasing() did only make the picture to appear in white but not black anymore. No other changes.

It is to note that I tried also simple examples from pyvista directly, getting the same issue.

You can try the same on the exact same settup using simply:

import pyvista as pv
from pyvista import examples

dataset = examples.download_st_helens()

plotter = pv.Plotter()

plotter.add_mesh(dataset)

plotter.show(jupyter_backend='static')

On two occasion I could get it to work but always after a restart of the kernel (without any other changes), the issue re-appeared.

UPDATE:

I could make the display in Visual studio work by simply using the 'html' jupyter backend. See the adapted code below.

import pyvista as pv
from pyvista import examples
pyvista.set_jupyter_backend('html')

dataset = examples.download_st_helens()

plotter = pv.Plotter()

plotter.add_mesh(dataset)

plotter.show()

However, I am facing the problem that I cannot export the image. E.g. I would want to make an export of the figure using

plotter.screenshot("filename.png")

This unfortunately gives mee the original issue with an all black image file.

I would appreciate any help on the export.

Upvotes: 1

Views: 763

Answers (1)

BilboMcBong
BilboMcBong

Reputation: 1

I ran into the exact same problem as you with a pretty similar setup and it seems that I found a workaround (up to more testing). I do not really understand why/how it works so i do a mere "recipe" for my setup.

Most likely you are aware of the installation guide for pyvista, if not have a look at

https://docs.pyvista.org/getting-started/installation

and there the section "Running on WSL". They give a nice description of what to do to for interactive plotting in WSL(2). If you already installed mini/anaconda it boils down to (READ FURTHER)

conda activate vtk_env
conda install nodejs  # required when importing pyvista in Jupyter
pip install jupyter pyvista[jupyter] trame

# To avoid "ModuleNotFoundError: No module named 'vtkOpenGLKitPython' " 
# when     importing vtk
# https://stackoverflow.com/q/32389599
# https://askubuntu.com/q/629692
sudo apt update && sudo apt install python-qt4 libgl1-mesa-glx

Now for the "recipe", in my system (x64)

  • Lenovo Think Pad
  • Microsoft Windows 11 Education Version 10.0.22361
  • Intel(R) Core(TM) Ultra 7 155U
  • wsl2 (Ubuntu 22.04)

I did the following installations in the fenicsx environment:

  1. sudo apt update
  2. sudo apt-get install libgl1-mesa-glx libegl1-mesa libxrandr2 libxrandr2 libxss1 libxcursor1 libxcomposite1 libasound2 libxi6 libxtst6
  3. install and initialize anaconda
  4. installed fenicsx, mpich, pyvista just as described on the fenicsx page using the conda packages
  5. used the first code block just for the fenicsx-environment and replaced sudo install python-qt4 by pip install pyqt5
  6. sudo apt-get install xvfb
  7. conda install notebook ipykernel
  8. python3 -m ipykernel install --user --name=fenicsx-env
  9. conda install -c conda-forge pyvista jupyterlab trame trame-vuetify trame-vtk ipywidgets
  10. dont forget to add
export DISPLAY=:99.0
export PYVISTA_OFF_SCREEN=true
Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
sleep 1 

to your .bashrc file

Some comments:

  • I am aware that I currently have installed conflicting packages (pyvista and maybe some more) so it could be very well that some of the above installation are not so important.
  • It seems that currently only jupyter-lab can be used for interactive plotting with pyvista (just as described on their page)
  • So I am currently using JupyterLab for interactive sessions with dolphinx. There are many explanations how to use jupyter lab from wsl. The line python3 -m ipykernel install --user --name=fenicsx-env makes the conda environment accessible from JupyterLab.
  • When I tried the Setup in VSCode it did not work but really only with JupyterLab ( I do not understand the dark magic behind this).
  • Maybe in your setup with the i7 processor and the intel graphics you also check your graphics driver as in https://learn.microsoft.com/en-us/windows/wsl/tutorials/gui-apps.

With this setup i can for example use

import pyvista as pv

sphere = pv.Sphere()

pl = pv.Plotter()
pl.add_mesh(sphere, show_edges=True)

pl.show()

to produce the sphere or in our use-cases of FEM you can use the code from the poisson example in fenicsx

from mpi4py import MPI
from dolfinx import mesh
domain = mesh.create_unit_square(MPI.COMM_WORLD, 8, 8, mesh.CellType.quadrilateral)

from dolfinx.fem import functionspace
V = functionspace(domain, ("Lagrange", 1))

from dolfinx import fem
uD = fem.Function(V)
uD.interpolate(lambda x: 1 + x[0]**2 + 2 * x[1]**2)

import numpy
# Create facet to cell connectivity required to determine boundary facets
tdim = domain.topology.dim
fdim = tdim - 1
domain.topology.create_connectivity(fdim, tdim)
boundary_facets = mesh.exterior_facet_indices(domain.topology)

boundary_dofs = fem.locate_dofs_topological(V, fdim, boundary_facets)
bc = fem.dirichletbc(uD, boundary_dofs)

import ufl
u = ufl.TrialFunction(V)
v = ufl.TestFunction(V)

from dolfinx import default_scalar_type
f = fem.Constant(domain, default_scalar_type(-6))

a = ufl.dot(ufl.grad(u), ufl.grad(v)) * ufl.dx
L = f * v * ufl.dx

from dolfinx.fem.petsc import LinearProblem
problem = LinearProblem(a, L, bcs=[bc], petsc_options={"ksp_type": "preonly", "pc_type": "lu"})
uh = problem.solve()

V2 = fem.functionspace(domain, ("Lagrange", 2))
uex = fem.Function(V2)
uex.interpolate(lambda x: 1 + x[0]**2 + 2 * x[1]**2)

L2_error = fem.form(ufl.inner(uh - uex, uh - uex) * ufl.dx)
error_local = fem.assemble_scalar(L2_error)
error_L2 = numpy.sqrt(domain.comm.allreduce(error_local, op=MPI.SUM))

error_max = numpy.max(numpy.abs(uD.x.array-uh.x.array))
# Only print the error on one process
if domain.comm.rank == 0:
    print(f"Error_L2 : {error_L2:.2e}")
    print(f"Error_max : {error_max:.2e}")

from dolfinx import plot
domain.topology.create_connectivity(tdim, tdim)
topology, cell_types, geometry = plot.vtk_mesh(domain, tdim)
grid = pv.UnstructuredGrid(topology, cell_types, geometry)

plotter = pv.Plotter()
plotter.add_mesh(grid, show_edges=True)

and

plotter.view_xy()
plotter.show()

to produce the mesh used in the FEM.

I hope this helps. If not hit me with further questions or your own considerations.

Caveat: This is my first answer on such a forum ever. So please dear stackoverflow community show some mercy. I would have commented first, but I do not have the necessary reputation. Also in these software things, I am completely self-taught so I often lack the fundamental understanding and fiddle around until it works. But of course I am looking forward to your feedback!

Upvotes: 0

Related Questions