{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%cd ..\n", "import sys\n", "\n", "sys.path.append(\"/workspaces/waloviz/src\")\n", "sys.path.append(\"/home/runner/work/waloviz/waloviz/src\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Controlling the responsiveness and size of a plot can be unintuitive. \n", "This page tries to guide you through the basics of sizing configuration and it's effect in different environments, to do that we need a frame of reference for what \"size\" means. \n", "\n", "Let's define two methods that will help us do just that:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import html\n", "from io import StringIO\n", "\n", "import panel as pn\n", "import waloviz as wv\n", "\n", "wv.extension()\n", "\n", "\n", "def iframe(x, height=400): # creates an HTML iframe with a certain height\n", " wv_html = StringIO()\n", " wv.save(x, wv_html)\n", " wv_html.seek(0)\n", " html_content = wv_html.read()\n", " escaped_html = html.escape(html_content)\n", " iframe_html = f''\n", " return pn.pane.HTML(\n", " iframe_html,\n", " height=height,\n", " sizing_mode=\"stretch_width\",\n", " styles={\"background\": \"#3d8063\"},\n", " )\n", "\n", "\n", "def cell(x): # displays normally\n", " return x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `iframe` function tries to simulate the effects of putting our WaloViz player in an iframe (or a browser window for that matter), while the `cell` function just runs normally in the notebook. \n", "These two situations may yield very different results in different configurations mostly because of their height, we'll try to cover a few of the common differences in behavior. \n", "\n", "Let's start by showing how the `iframe` is different from the `cell`:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = pn.widgets.StaticText(value=\"Hello!\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "cell(x)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "iframe(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As you can see the `cell` adjusts it's height to fit the size of the content, in this case - the text \"Hello!\" \n", "The `iframe` on the other hand colors a green area, this area is of a constant height (300 in the previous example), and a responsive width. \n", "Now let's see a simple WaloViz player in those two scenarios:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "\n", "noise = (np.random.randn(8000) / 100, 8000)\n", "x = wv.Audio(noise, minimal=True)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "cell(x)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "iframe(x)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "wv.save(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As you can see, the results are very similar, but the `cell` has no margins while the `iframe` has some green margins on the bottom. \n", "Try to change the width of the window (you can't on mobile devices) and see how the player responsively scales to fit the width of the screen in both cases. \n", "\n", "The default behavior of the WaloViz player is to scale the height and width to fit the container, while keeping the aspect ratio (`width/height`) at a constant, by default 3.5.\n", "\n", "Let's try to increase the `aspect_ratio`:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = wv.Audio(noise, minimal=True, aspect_ratio=5.0)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "cell(x)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "iframe(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As you can see the player smaller in height when compared to its width, the width did not change because only the width is limited to a given maximum.\n", "\n", "Again, try to change the width of the window to see the responsiveness of the width and height. \n", "Now, let's set a constant `height` value:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = wv.Audio(noise, minimal=True, height=250)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "cell(x)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "iframe(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Try to change the width of the window, notice how this time only the width changes, the height stays constant. \n", "\n", "Now let's try to set a constant width: " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = wv.Audio(noise, minimal=True, width=600)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "cell(x)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "iframe(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here there is a noticeable difference, why is that? \n", "By setting the `width` or `height`, the `aspect_ratio` is disabled. \n", "\n", "When we set the `height` to 250, the `width` was still responsive. \n", "The same is true when we set the `width` to 600, the `height` is still responsive. \n", "\n", "In the `cell` case, the height is minimized as much as possible, up to the minimum of WaloViz, this is the default behavior of jupyter notebooks. \n", "In the `iframe` case, the height is resposive and adjusts itself to fit the maximum available height. \n", "\n", "Let's see one last case, where both width and height are fixed:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = wv.Audio(noise, minimal=True, width=600, height=250)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "cell(x)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "iframe(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "These are not responsive at all, but will remain static no matter what.\n", "\n", "To make the player fill the entire container no matter what, you should use the `sizing_mode=\"stretch_both\"` option:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = wv.Audio(noise, minimal=True, sizing_mode=\"stretch_both\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "cell(x)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "iframe(x)" ] } ], "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.10.14" } }, "nbformat": 4, "nbformat_minor": 2 }