K3D Headless Screenshot

[1]:
%%writefile headless_k3d.py
import numpy as np

import k3d
from k3d.headless import k3d_remote, get_headless_firefox_driver


def generate():
    def iterate(length, x, y, z):
        nl = length // 3

        if nl < 1:
            return

        margin = (nl - 1) // 2

        voxels[z - margin:z + margin + 1, y - margin:y + margin + 1, :] = 0
        voxels[z - margin:z + margin + 1, :, x - margin:x + margin + 1] = 0
        voxels[:, y - margin:y + margin + 1, x - margin:x + margin + 1] = 0

        for ix, iy, iz in np.ndindex((3, 3, 3)):
            if (1 if ix != 1 else 0) + (1 if iy != 1 else 0) + (1 if iz != 1 else 0) != 2:
                iterate(nl, x + (ix - 1) * nl, y +
                        (iy - 1) * nl, z + (iz - 1) * nl)

    iteration = 4
    size = 3 ** iteration

    voxels = np.ones((size, size, size))

    iterate(size, size // 2, size // 2, size // 2)

    plt_voxels = k3d.voxels(voxels.astype(np.uint8),
                            color_map=(0xfdfe03), outlines=True)

    plot = k3d.plot(grid_visible=False,
                    camera_auto_fit=False,
                    screenshot_scale=1,
                    axes_helper=0)
    plot += plt_voxels

    plot.camera = [98.5152, -60.0912, 88.9902,
                   43.4731, 37.6014, 31.5219,
                   -0.2226, 0.3405, 0.9135]

    headless = k3d_remote(plot, get_headless_firefox_driver(), width=800, height=800)

    headless.sync(hold_until_refreshed=True)
    headless.camera_reset(1)

    screenshot = headless.get_screenshot()
    headless.close()

    return screenshot
png_data = generate()
from PIL import Image as PILImage
from io import BytesIO
with open('headless_k3d.png','wb') as f:
    f.write(png_data)
# help(ret)
Writing headless_k3d.py
[2]:
!python3 headless_k3d.py
Traceback (most recent call last):
  File "/home/docs/checkouts/readthedocs.org/user_builds/spanag-rtd-tutorial/checkouts/latest/docs/source/headless_k3d.py", line 54, in <module>
    png_data = generate()
  File "/home/docs/checkouts/readthedocs.org/user_builds/spanag-rtd-tutorial/checkouts/latest/docs/source/headless_k3d.py", line 47, in generate
    headless.sync(hold_until_refreshed=True)
  File "/home/docs/checkouts/readthedocs.org/user_builds/spanag-rtd-tutorial/envs/latest/lib/python3.10/site-packages/k3d/headless.py", line 107, in sync
    self.browser.execute_script("k3dRefresh()")
  File "/home/docs/checkouts/readthedocs.org/user_builds/spanag-rtd-tutorial/envs/latest/lib/python3.10/site-packages/selenium/webdriver/remote/webdriver.py", line 407, in execute_script
    return self.execute(command, {"script": script, "args": converted_args})["value"]
  File "/home/docs/checkouts/readthedocs.org/user_builds/spanag-rtd-tutorial/envs/latest/lib/python3.10/site-packages/selenium/webdriver/remote/webdriver.py", line 347, in execute
    self.error_handler.check_response(response)
  File "/home/docs/checkouts/readthedocs.org/user_builds/spanag-rtd-tutorial/envs/latest/lib/python3.10/site-packages/selenium/webdriver/remote/errorhandler.py", line 229, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.JavascriptException: Message: ReferenceError: k3dRefresh is not defined
Stacktrace:
@http://localhost:8080/headless.html:2:7
@http://localhost:8080/headless.html:3:8

[3]:
import IPython
IPython.display.Image('headless_k3d.png')
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
File ~/checkouts/readthedocs.org/user_builds/spanag-rtd-tutorial/envs/latest/lib/python3.10/site-packages/IPython/core/display.py:1045, in Image._data_and_metadata(self, always_both)
   1044 try:
-> 1045     b64_data = b2a_base64(self.data, newline=False).decode("ascii")
   1046 except TypeError as e:

TypeError: a bytes-like object is required, not 'str'

The above exception was the direct cause of the following exception:

FileNotFoundError                         Traceback (most recent call last)
File ~/checkouts/readthedocs.org/user_builds/spanag-rtd-tutorial/envs/latest/lib/python3.10/site-packages/IPython/core/formatters.py:977, in MimeBundleFormatter.__call__(self, obj, include, exclude)
    974     method = get_real_method(obj, self.print_method)
    976     if method is not None:
--> 977         return method(include=include, exclude=exclude)
    978     return None
    979 else:

File ~/checkouts/readthedocs.org/user_builds/spanag-rtd-tutorial/envs/latest/lib/python3.10/site-packages/IPython/core/display.py:1035, in Image._repr_mimebundle_(self, include, exclude)
   1033 if self.embed:
   1034     mimetype = self._mimetype
-> 1035     data, metadata = self._data_and_metadata(always_both=True)
   1036     if metadata:
   1037         metadata = {mimetype: metadata}

File ~/checkouts/readthedocs.org/user_builds/spanag-rtd-tutorial/envs/latest/lib/python3.10/site-packages/IPython/core/display.py:1047, in Image._data_and_metadata(self, always_both)
   1045     b64_data = b2a_base64(self.data, newline=False).decode("ascii")
   1046 except TypeError as e:
-> 1047     raise FileNotFoundError(
   1048         "No such file or directory: '%s'" % (self.data)) from e
   1049 md = {}
   1050 if self.metadata:

FileNotFoundError: No such file or directory: 'headless_k3d.png'
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
File ~/checkouts/readthedocs.org/user_builds/spanag-rtd-tutorial/envs/latest/lib/python3.10/site-packages/IPython/core/display.py:1045, in Image._data_and_metadata(self, always_both)
   1044 try:
-> 1045     b64_data = b2a_base64(self.data, newline=False).decode("ascii")
   1046 except TypeError as e:

TypeError: a bytes-like object is required, not 'str'

The above exception was the direct cause of the following exception:

FileNotFoundError                         Traceback (most recent call last)
File ~/checkouts/readthedocs.org/user_builds/spanag-rtd-tutorial/envs/latest/lib/python3.10/site-packages/IPython/core/formatters.py:347, in BaseFormatter.__call__(self, obj)
    345     method = get_real_method(obj, self.print_method)
    346     if method is not None:
--> 347         return method()
    348     return None
    349 else:

File ~/checkouts/readthedocs.org/user_builds/spanag-rtd-tutorial/envs/latest/lib/python3.10/site-packages/IPython/core/display.py:1067, in Image._repr_png_(self)
   1065 def _repr_png_(self):
   1066     if self.embed and self.format == self._FMT_PNG:
-> 1067         return self._data_and_metadata()

File ~/checkouts/readthedocs.org/user_builds/spanag-rtd-tutorial/envs/latest/lib/python3.10/site-packages/IPython/core/display.py:1047, in Image._data_and_metadata(self, always_both)
   1045     b64_data = b2a_base64(self.data, newline=False).decode("ascii")
   1046 except TypeError as e:
-> 1047     raise FileNotFoundError(
   1048         "No such file or directory: '%s'" % (self.data)) from e
   1049 md = {}
   1050 if self.metadata:

FileNotFoundError: No such file or directory: 'headless_k3d.png'
[3]:
<IPython.core.display.Image object>