Last active
April 25, 2019 08:28
-
-
Save deeplook/3fcd176b76cbbce4349c9156f051c30d to your computer and use it in GitHub Desktop.
Save/restore ipyvolume camera state
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Save/restore ipyvolume camera state\n", | |
"\n", | |
"In this notebook you can create a simple 3D plot with ipyvolume inside a JupyterLab \"Sidecar\" and use two buttons to *Save* and *Restore* the camera \"state\". So you can save the state, interact wildly with the 3D plot (changing zoom, position, etc.) and restore to the previously saved state.\n", | |
"\n", | |
"This could evolve into a UI that allows to take snapshots of the current state and restore them at some later moment, maybe even with a slider widget... To be continued... " | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import numpy as np\n", | |
"import ipyvolume as ipv\n", | |
"from ipywidgets import Button, HBox\n", | |
"from sidecar import Sidecar" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"class CameraController:\n", | |
" \"\"\"\n", | |
" A simple controller to save and restore the current ipyvolume camera state.\n", | |
" \"\"\"\n", | |
" def __init__(self):\n", | |
" \"Intantiate with a simple two button UI.\"\n", | |
" self.state = {}\n", | |
" self.save_btn = Button(description='Save')\n", | |
" self.save_btn.on_click(self.save_button_clicked)\n", | |
" self.restore_btn = Button(description='Restore')\n", | |
" self.restore_btn.on_click(self.restore_button_clicked)\n", | |
" self.ui = HBox([self.save_btn, self.restore_btn])\n", | |
"\n", | |
" def save_button_clicked(self, b):\n", | |
" \"Save current state.\"\n", | |
" self.state = dict(\n", | |
" pos = ipv.current.figure.camera.position,\n", | |
" quaternion = ipv.current.figure.camera.quaternion,\n", | |
" projectionMatrix = ipv.current.figure.camera.projectionMatrix,\n", | |
" )\n", | |
" \n", | |
" def restore_button_clicked(self, b):\n", | |
" \"Restore previously taken state.\"\n", | |
" state = self.state\n", | |
" ipv.current.figure.camera.position = state['pos']\n", | |
" ipv.current.figure.camera.quaternion = state['quaternion']\n", | |
" ipv.current.figure.camera.projectionMatrix = state['projectionMatrix']" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Create the two-button \"UI\"." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"camcon = CameraController()\n", | |
"camcon.ui" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Create a simple 3D plot inside a sidecar." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"x, y, z = np.random.random((3, 10000))\n", | |
"sc = Sidecar(title='3D')\n", | |
"with sc:\n", | |
" ipv.figure()\n", | |
" p = ipv.scatter(\n", | |
" x, y, z, size=1, color='red', marker='sphere')\n", | |
" ipv.show()" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Notice the buglet when changing the plot's resolution (width/height) and resetting the view with the respective built-in iconized mini-buttons! This seems to happen also without Sidecar and might be a buglet in ipyvolume itself." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Create simple plot without any sidecar." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"ipv.figure()\n", | |
"x, y, z = np.random.random((3, 10000))\n", | |
"p = ipv.scatter(x, y, z, size=1, color='red', marker='sphere')\n", | |
"ipv.show()" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3", | |
"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.7.3" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment