{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%matplotlib widget" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig, ax = plt.subplots()\n", "fig.canvas.width = '7in'\n", "fig.canvas.height= '5in'\n", "\n", "# if I hide the header here, I get a libpng error\n", "# fig.canvas.header_visible = False\n", "\n", "ax.plot([1,2,3], [4,5,3])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# hiding after rendering works\n", "fig.canvas.header_visible = False" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# hiding together with calls to toolbar options, work.\n", "fig, ax = plt.subplots()\n", "fig.canvas.width = '7in'\n", "fig.canvas.height= '5in'\n", "\n", "fig.canvas.toolbar_visible = False\n", "fig.canvas.header_visible = False\n", "\n", "ax.plot([1,2,3], [4,5,3])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# When using the `widget` backend from ipympl,\n", "# fig.canvas is a proper Jupyter interactive widget, which can be embedded in\n", "# an ipywidgets layout. See https://ipywidgets.readthedocs.io/en/stable/examples/Layout%20Templates.html\n", "\n", "# One can bound figure attributes to other widget values.\n", "from ipywidgets import AppLayout, FloatSlider\n", "\n", "plt.ioff()\n", "\n", "slider = FloatSlider(\n", " orientation='horizontal',\n", " description='Factor:',\n", " value=1.0,\n", " min=0.02,\n", " max=2.0\n", ")\n", "\n", "slider.layout.margin = '0px 30% 0px 30%'\n", "slider.layout.width = '40%'\n", "\n", "fig = plt.figure()\n", "fig.canvas.header_visible = False\n", "fig.canvas.layout.min_height = '400px'\n", "plt.title('Plotting: y=sin({} * x)'.format(slider.value))\n", "\n", "x = np.linspace(0, 20, 500)\n", "\n", "lines = plt.plot(x, np.sin(slider.value * x))\n", "\n", "def update_lines(change):\n", " plt.title('Plotting: y=sin({} * x)'.format(change.new))\n", " lines[0].set_data(x, np.sin(change.new * x))\n", " fig.canvas.draw()\n", " fig.canvas.flush_events()\n", "\n", "slider.observe(update_lines, names='value')\n", "\n", "AppLayout(\n", " center=fig.canvas,\n", " footer=slider,\n", " pane_heights=[0, 6, 1]\n", ")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "from matplotlib.patches import Shadow\n", "\n", "# make a square figure and axes\n", "fig = plt.figure(figsize=(6, 6))\n", "ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])\n", "\n", "labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'\n", "fracs = [15, 30, 45, 10]\n", "\n", "explode = (0, 0.05, 0, 0)\n", "\n", "# We want to draw the shadow for each pie but we will not use \"shadow\"\n", "# option as it does'n save the references to the shadow patches.\n", "pies = ax.pie(fracs, explode=explode, labels=labels, autopct='%1.1f%%')\n", "\n", "for w in pies[0]:\n", " # set the id with the label.\n", " w.set_gid(w.get_label())\n", "\n", " # we don't want to draw the edge of the pie\n", " w.set_edgecolor(\"none\")\n", "\n", "for w in pies[0]:\n", " # create shadow patch\n", " s = Shadow(w, -0.01, -0.01)\n", " s.set_gid(w.get_gid() + \"_shadow\")\n", " s.set_zorder(w.get_zorder() - 0.1)\n", " ax.add_patch(s)\n", "\n", "\n", "# save\n", "from io import BytesIO\n", "f = BytesIO()\n", "plt.savefig(f, format=\"svg\")\n", "\n", "import xml.etree.cElementTree as ET\n", "\n", "\n", "# filter definition for shadow using a gaussian blur\n", "# and lightening effect.\n", "# The lightening filter is copied from http://www.w3.org/TR/SVG/filters.html\n", "\n", "# I tested it with Inkscape and Firefox3. \"Gaussian blur\" is supported\n", "# in both, but the lightening effect only in the Inkscape. Also note\n", "# that, Inkscape's exporting also may not support it.\n", "\n", "filter_def = \"\"\"\n", " \n", " \n", " \n", " \n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\"\"\"\n", "\n", "\n", "tree, xmlid = ET.XMLID(f.getvalue())\n", "\n", "# insert the filter definition in the svg dom tree.\n", "tree.insert(0, ET.XML(filter_def))\n", "\n", "for i, pie_name in enumerate(labels):\n", " pie = xmlid[pie_name]\n", " pie.set(\"filter\", 'url(#MyFilter)')\n", "\n", " shadow = xmlid[pie_name + \"_shadow\"]\n", " shadow.set(\"filter\", 'url(#dropshadow)')\n", "\n", "fn = \"svg_filter_pie.svg\"\n", "print(\"Saving '%s'\" % fn)\n", "ET.ElementTree(tree).write(fn)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%matplotlib widget\n", "import ipywidgets as widgets\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "# set up plot\n", "fig, ax = plt.subplots(figsize=(6, 4))\n", "ax.set_ylim([-4, 4])\n", "ax.grid(True)\n", " \n", "# generate x values\n", "x = np.linspace(0, 2 * np.pi, 100)\n", " \n", " \n", "def my_sine(x, w, amp, phi):\n", " \"\"\"\n", " Return a sine for x with angular frequeny w and amplitude amp.\n", " \"\"\"\n", " return amp*np.sin(w * (x-phi))\n", " \n", " \n", "@widgets.interact(w=(0, 10, 1), amp=(0, 4, .1), phi=(0, 2*np.pi+0.01, 0.01))\n", "def update(w = 1.0, amp=1, phi=0):\n", " \"\"\"Remove old lines from plot and plot new one\"\"\"\n", " [l.remove() for l in ax.lines]\n", " ax.plot(x, my_sine(x, w, amp, phi), color='C0')\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%matplotlib inline\n", "import time\n", "import pylab as pl\n", "from IPython import display\n", "for i in range(10):\n", " pl.plot(pl.randn(100))\n", " display.clear_output(wait=True)\n", " display.display(pl.gcf())\n", " time.sleep(1.0)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "!pip install drawsvg" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import drawSvg as draw" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "from IPython.display import SVG, display" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "d = draw.Drawing(200, 200, origin='center')" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "c = draw.Circle(0, 0, 20, fill='red')" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "d.append(c)" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "" ], "text/plain": [ "" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "c0 = d.allElements()[0]" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'cx': 0, 'cy': 0, 'r': 30, 'fill': 'red'}" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "c0.args" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [], "source": [ "c0.args={'cx': 0, 'cy': 0, 'r': 25, 'fill': 'red'}" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "r = draw.Rectangle(5,5,5,3,fill='blue')" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [], "source": [ "d.append(r)" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'x': 25, 'y': 25, 'width': 25, 'height': 10, 'fill': 'blue'}" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.args" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [], "source": [ "r.args={'x': 25, 'y': 25, 'width': 25, 'height': 20, 'fill': 'blue'}" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "!pip3 install hyperbolic" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "application/javascript": [ "\n", "require.undef('drawingview');\n", "\n", "define('drawingview', ['@jupyter-widgets/base'], function(widgets) {\n", " var DrawingView = widgets.DOMWidgetView.extend({\n", " render: function() {\n", " this.container = document.createElement('a');\n", " this.image_changed();\n", " this.container.appendChild(this.svg_view);\n", " this.el.appendChild(this.container);\n", " this.model.on('change:_image', this.image_changed, this);\n", " this.model.on('change:_mousemove_blocked', this.block_changed,\n", " this);\n", " this.model.on('change:frame_delay', this.delay_changed,\n", " this);\n", " this.model.on('change:_frame_blocked', this.delay_changed,\n", " this);\n", " this.model.on('change:disable', this.delay_changed,\n", " this);\n", " this.delay_changed();\n", " },\n", " image_changed: function() {\n", " this.container.innerHTML = this.model.get('_image');\n", " this.svg_view = this.container.getElementsByTagName('svg')[0];\n", " this.cursor_point = this.svg_view.createSVGPoint();\n", " this.register_events();\n", " },\n", " last_move: null,\n", " last_mousemove_blocked: null,\n", " last_timer: null,\n", " block_changed: function() {\n", " var widget = this;\n", " window.setTimeout(function() {\n", " if (widget.model.get('_mousemove_blocked')\n", " != widget.last_mousemove_blocked && widget.last_move) {\n", " widget.send_mouse_event('mousemove', widget.last_move);\n", " }\n", " }, 0);\n", " },\n", " send_mouse_event: function(name, e) {\n", " this.last_move = null;\n", " if (this.model.get('disable')) {\n", " return;\n", " }\n", "\n", " this.cursor_point.x = e.clientX;\n", " this.cursor_point.y = e.clientY;\n", " var svg_pt = this.cursor_point.matrixTransform(\n", " this.svg_view.getScreenCTM().inverse());\n", "\n", " this.send({\n", " name: name,\n", " x: svg_pt.x,\n", " y: -svg_pt.y,\n", " type: e.type,\n", " button: e.button,\n", " buttons: e.buttons,\n", " shiftKey: e.shiftKey,\n", " altKey: e.altKey,\n", " ctrlKey: e.ctrlKey,\n", " metaKey: e.metaKey,\n", " clientX: e.clientX,\n", " clientY: e.clientY,\n", " movementX: e.movementX,\n", " movementY: e.movementY,\n", " timeStamp: e.timeStamp,\n", " targetId: e.target ? e.target.id : null,\n", " currentTargetId: e.currentTarget ? e.currentTarget.id : null,\n", " relatedTargetId: e.relatedTarget ? e.relatedTarget.id : null,\n", " });\n", " },\n", " delay_changed: function() {\n", " var widget = this;\n", " window.clearTimeout(widget.last_timer);\n", " if (widget.model.get('disable')) {\n", " return;\n", " }\n", " var delay = widget.model.get('frame_delay');\n", " if (delay > 0) {\n", " widget.last_timer = window.setTimeout(function() {\n", " widget.send_timed_event('timed');\n", " }, delay);\n", " }\n", " },\n", " send_timed_event: function(name) {\n", " if (this.model.get('disable')) {\n", " return;\n", " }\n", "\n", " this.send({\n", " name: name,\n", " });\n", " },\n", " register_events: function() {\n", " var widget = this;\n", " this.svg_view.addEventListener('mousedown', function(e) {\n", " e.preventDefault();\n", " widget.send_mouse_event('mousedown', e);\n", " });\n", " this.svg_view.addEventListener('mousemove', function(e) {\n", " e.preventDefault();\n", " if (widget.model.get('_mousemove_blocked')\n", " == widget.last_mousemove_blocked) {\n", " widget.last_move = e;\n", " } else {\n", " widget.send_mouse_event('mousemove', e);\n", " }\n", " });\n", " this.svg_view.addEventListener('mouseup', function(e) {\n", " e.preventDefault();\n", " widget.send_mouse_event('mouseup', e);\n", " });\n", " }\n", " });\n", "\n", " return {\n", " DrawingView: DrawingView\n", " };\n", "});\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "334798dc0fde4ed692ac15851a340d8c", "version_major": 2, "version_minor": 0 }, "text/plain": [ "DrawingWidget()" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import drawSvg as draw\n", "from drawSvg.widgets import DrawingWidget\n", "import hyperbolic.poincare.shapes as hyper # pip3 install hyperbolic\n", "\n", "# Create drawing\n", "d = draw.Drawing(2, 2, origin='center')\n", "d.setRenderSize(500)\n", "d.append(draw.Circle(0, 0, 1, fill='orange'))\n", "group = draw.Group()\n", "d.append(group)\n", "\n", "# Update the drawing based on user input\n", "click_list = []\n", "def redraw(points):\n", " group.children.clear()\n", " for x1, y1 in points:\n", " for x2, y2 in points:\n", " if (x1, y1) == (x2, y2): continue\n", " p1 = hyper.Point.fromEuclid(x1, y1)\n", " p2 = hyper.Point.fromEuclid(x2, y2)\n", " if p1.distanceTo(p2) <= 2:\n", " line = hyper.Line.fromPoints(*p1, *p2, segment=True)\n", " group.draw(line, hwidth=0.2, fill='white')\n", " for x, y in points:\n", " p = hyper.Point.fromEuclid(x, y)\n", " group.draw(hyper.Circle.fromCenterRadius(p, 0.1),\n", " fill='green')\n", "redraw(click_list)\n", "\n", "# Create interactive widget and register mouse events\n", "widget = DrawingWidget(d)\n", "@widget.mousedown\n", "def mousedown(widget, x, y, info):\n", " if (x**2 + y**2) ** 0.5 + 1e-5 < 1:\n", " click_list.append((x, y))\n", " redraw(click_list)\n", " widget.refresh()\n", "@widget.mousemove\n", "def mousemove(widget, x, y, info):\n", " if (x**2 + y**2) ** 0.5 + 1e-5 < 1:\n", " redraw(click_list + [(x, y)])\n", " widget.refresh()\n", "widget" ] } ], "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.8.5" } }, "nbformat": 4, "nbformat_minor": 4 }