{ "cells": [ { "cell_type": "markdown", "id": "60e3ac1d", "metadata": {}, "source": [ "# Plotting Examples with Matplotlib and Plotly\n", "\n", "This notebook demonstrates how to visualize broadbean pulse sequences using both **matplotlib** and **plotly** backends.\n", "\n", "## Table of Contents\n", "\n", "* [Setup](#Setup)\n", "* [Creating Sample Pulses](#Creating-Sample-Pulses)\n", "* [Matplotlib Backend](#Matplotlib-Backend)\n", " * [Plotting Blueprints](#Plotting-Blueprints-with-Matplotlib)\n", " * [Plotting Elements](#Plotting-Elements-with-Matplotlib)\n", " * [Plotting Sequences](#Plotting-Sequences-with-Matplotlib)\n", "* [Plotly Backend](#Plotly-Backend)\n", " * [Plotting Blueprints](#Plotting-Blueprints-with-Plotly)\n", " * [Plotting Elements](#Plotting-Elements-with-Plotly)\n", " * [Plotting Sequences](#Plotting-Sequences-with-Plotly)\n", "* [Comparing Backends](#Comparing-Backends)" ] }, { "cell_type": "markdown", "id": "e7beb180", "metadata": {}, "source": [ "## Setup\n", "\n", "First, let's import the necessary modules." ] }, { "cell_type": "code", "execution_count": null, "id": "39adffe2", "metadata": {}, "outputs": [], "source": [ "import matplotlib as mpl\n", "\n", "import broadbean as bb\n", "from broadbean.plotting import plotter\n", "\n", "# Configure matplotlib for better display\n", "mpl.rcParams[\"figure.figsize\"] = (10, 4)\n", "mpl.rcParams[\"figure.subplot.bottom\"] = 0.15" ] }, { "cell_type": "markdown", "id": "0adf4265", "metadata": {}, "source": [ "## Creating Sample Pulses\n", "\n", "Let's create some sample blueprints, elements, and sequences that we'll use for plotting demonstrations." ] }, { "cell_type": "code", "execution_count": null, "id": "7bd68572", "metadata": {}, "outputs": [], "source": [ "# Get the built-in pulse atoms\n", "ramp = bb.PulseAtoms.ramp # args: start, stop\n", "sine = bb.PulseAtoms.sine # args: freq, ampl, off, phase\n", "\n", "# Create a simple blueprint with multiple segments\n", "bp = bb.BluePrint()\n", "bp.insertSegment(0, ramp, (0, 0.5e-3), name=\"ramp_up\", dur=2e-6)\n", "bp.insertSegment(1, sine, (2e6, 0.5e-3, 0.5e-3, 0), name=\"oscillation\", dur=3e-6)\n", "bp.insertSegment(2, ramp, (0.5e-3, 0), name=\"ramp_down\", dur=2e-6)\n", "bp.setSR(1e9) # 1 GS/s sample rate\n", "\n", "# Add some markers for demonstration\n", "bp.setSegmentMarker(\"ramp_up\", (0, 1e-6), 1) # Marker 1 during first half of ramp_up\n", "bp.setSegmentMarker(\"oscillation\", (0.5e-6, 2e-6), 2) # Marker 2 during oscillation\n", "\n", "print(\"Blueprint created:\")\n", "bp.showPrint()" ] }, { "cell_type": "code", "execution_count": null, "id": "79077cf1", "metadata": {}, "outputs": [], "source": [ "# Create a second blueprint for multi-channel demonstration\n", "bp2 = bb.BluePrint()\n", "bp2.insertSegment(0, ramp, (0, -0.3e-3), name=\"init\", dur=2e-6)\n", "bp2.insertSegment(1, ramp, (-0.3e-3, -0.3e-3), name=\"hold\", dur=3e-6)\n", "bp2.insertSegment(2, ramp, (-0.3e-3, 0), name=\"release\", dur=2e-6)\n", "bp2.setSR(1e9)\n", "\n", "print(\"Second blueprint created:\")\n", "bp2.showPrint()" ] }, { "cell_type": "code", "execution_count": null, "id": "3d1d73c6", "metadata": {}, "outputs": [], "source": [ "# Create an element with two channels\n", "elem = bb.Element()\n", "elem.addBluePrint(1, bp)\n", "elem.addBluePrint(2, bp2)\n", "\n", "print(f\"Element created with {len(elem._data)} channels\")\n", "print(f\"Total duration: {bp.duration * 1e6:.1f} µs\")" ] }, { "cell_type": "code", "execution_count": null, "id": "e26ba32c", "metadata": {}, "outputs": [], "source": [ "# Create a sequence with multiple positions\n", "seq = bb.Sequence()\n", "seq.setSR(1e9)\n", "\n", "# Add the element at position 1\n", "seq.addElement(1, elem)\n", "\n", "# Create a variation of the element for position 2\n", "bp3 = bp.copy()\n", "bp3.changeArg(\"oscillation\", \"freq\", 4e6) # Double the frequency\n", "\n", "elem2 = bb.Element()\n", "elem2.addBluePrint(1, bp3)\n", "elem2.addBluePrint(2, bp2)\n", "\n", "seq.addElement(2, elem2)\n", "\n", "# Set AWG specs\n", "seq.setChannelAmplitude(1, 2.5) # 2.5 V amplitude\n", "seq.setChannelAmplitude(2, 2.5)\n", "seq.setChannelOffset(1, 0)\n", "seq.setChannelOffset(2, 0)\n", "\n", "print(f\"Sequence created with {seq.length_sequenceelements} positions\")" ] }, { "cell_type": "markdown", "id": "767e4e32", "metadata": {}, "source": [ "## Matplotlib Backend\n", "\n", "The matplotlib backend is the default plotting backend. It creates static plots that are great for documentation and publications." ] }, { "cell_type": "markdown", "id": "45bab40f", "metadata": {}, "source": [ "### Plotting Blueprints with Matplotlib" ] }, { "cell_type": "code", "execution_count": null, "id": "4e740341", "metadata": {}, "outputs": [], "source": [ "# Plot a blueprint using matplotlib (default backend)\n", "fig = plotter(bp)\n", "\n", "# The plotter returns the matplotlib figure, which can be customized further\n", "fig.suptitle(\"Blueprint with Matplotlib\", fontsize=12, y=1.02)" ] }, { "cell_type": "code", "execution_count": null, "id": "a7899c1c", "metadata": {}, "outputs": [], "source": [ "# Explicitly specify the matplotlib backend\n", "fig = plotter(bp, backend=\"matplotlib\")\n", "fig.suptitle(\"Explicit Matplotlib Backend\", fontsize=12, y=1.02)" ] }, { "cell_type": "markdown", "id": "3b0e0285", "metadata": {}, "source": [ "### Plotting Elements with Matplotlib\n", "\n", "Elements show all channels side by side." ] }, { "cell_type": "code", "execution_count": null, "id": "7e39c96e", "metadata": {}, "outputs": [], "source": [ "# Plot the multi-channel element\n", "fig = plotter(elem, backend=\"matplotlib\")\n", "fig.suptitle(\"Two-Channel Element with Matplotlib\", fontsize=12, y=1.02)" ] }, { "cell_type": "markdown", "id": "f71b7559", "metadata": {}, "source": [ "### Plotting Sequences with Matplotlib\n", "\n", "Sequences show all positions and channels in a grid layout." ] }, { "cell_type": "code", "execution_count": null, "id": "8f801217", "metadata": {}, "outputs": [], "source": [ "# Plot the full sequence\n", "fig = plotter(seq, backend=\"matplotlib\")\n", "fig.suptitle(\"Sequence with Matplotlib (2 positions × 2 channels)\", fontsize=12, y=1.02)" ] }, { "cell_type": "markdown", "id": "460faec5", "metadata": {}, "source": [ "## Plotly Backend\n", "\n", "The plotly backend creates interactive plots that allow zooming, panning, and hovering over data points.\n", "\n", "**Note:** To use the plotly backend, you need to have plotly installed:\n", "```bash\n", "pip install plotly\n", "```\n", "or\n", "```bash\n", "pip install broadbean[plotly]\n", "```" ] }, { "cell_type": "markdown", "id": "ccca8d17", "metadata": {}, "source": [ "### Plotting Blueprints with Plotly" ] }, { "cell_type": "code", "execution_count": null, "id": "ad26a427", "metadata": {}, "outputs": [], "source": [ "# Plot a blueprint using the plotly backend\n", "fig = plotter(bp, backend=\"plotly\")\n", "\n", "# Update the layout title\n", "fig.update_layout(title=\"Blueprint with Plotly - Interactive!\")\n", "fig.show()" ] }, { "cell_type": "markdown", "id": "2b717e77", "metadata": {}, "source": [ "### Plotting Elements with Plotly" ] }, { "cell_type": "code", "execution_count": null, "id": "0f644f74", "metadata": {}, "outputs": [], "source": [ "# Plot the multi-channel element with plotly\n", "fig = plotter(elem, backend=\"plotly\")\n", "fig.update_layout(\n", " title=\"Two-Channel Element with Plotly\",\n", " height=500, # Adjust height for better visibility\n", ")\n", "fig.show()" ] }, { "cell_type": "markdown", "id": "d11a495c", "metadata": {}, "source": [ "### Plotting Sequences with Plotly" ] }, { "cell_type": "code", "execution_count": null, "id": "2b1b7453", "metadata": {}, "outputs": [], "source": [ "# Plot the full sequence with plotly\n", "fig = plotter(seq, backend=\"plotly\")\n", "fig.update_layout(title=\"Sequence with Plotly (2 positions × 2 channels)\", height=600)\n", "fig.show()" ] }, { "cell_type": "markdown", "id": "1fb15e19", "metadata": {}, "source": [ "## Comparing Backends\n", "\n", "Here's a quick summary of when to use each backend:\n", "\n", "| Feature | Matplotlib | Plotly |\n", "|---------|------------|--------|\n", "| Interactive zoom/pan | ❌ | ✅ |\n", "| Hover information | ❌ | ✅ |\n", "| Static export (PNG, PDF) | ✅ Excellent | ✅ Good |\n", "| Publication quality | ✅ | ✅ |\n", "| Jupyter notebook | ✅ | ✅ |\n", "| No extra dependencies | ✅ | ❌ (requires plotly) |\n", "\n", "**Recommendations:**\n", "- Use **matplotlib** for publications, reports, and when you need fine control over the figure styling.\n", "- Use **plotly** for interactive exploration, debugging pulse shapes, and presentations." ] }, { "cell_type": "code", "execution_count": null, "id": "677aeb46", "metadata": {}, "outputs": [], "source": [ "# Create a more complex blueprint to showcase the backends\n", "bp_complex = bb.BluePrint()\n", "bp_complex.insertSegment(0, ramp, (0, 1e-3), name=\"charge\", dur=1e-6)\n", "bp_complex.insertSegment(1, sine, (5e6, 0.2e-3, 1e-3, 0), name=\"pulse\", dur=2e-6)\n", "bp_complex.insertSegment(2, ramp, (1e-3, 0.5e-3), name=\"measure\", dur=1e-6)\n", "bp_complex.insertSegment(3, ramp, (0.5e-3, 0.5e-3), name=\"hold\", dur=2e-6)\n", "bp_complex.insertSegment(4, ramp, (0.5e-3, 0), name=\"reset\", dur=1e-6)\n", "bp_complex.setSR(1e9)\n", "\n", "# Add markers\n", "bp_complex.setSegmentMarker(\"pulse\", (0, 2e-6), 1)\n", "bp_complex.setSegmentMarker(\"measure\", (0, 1e-6), 2)\n", "\n", "print(\"Complex blueprint structure:\")\n", "bp_complex.showPrint()" ] }, { "cell_type": "code", "execution_count": null, "id": "1a7edcb9", "metadata": {}, "outputs": [], "source": [ "# Matplotlib version\n", "print(\"Matplotlib output:\")\n", "fig_mpl = plotter(bp_complex, backend=\"matplotlib\")\n", "fig_mpl.suptitle(\"Complex Pulse - Matplotlib\", y=1.02)" ] }, { "cell_type": "code", "execution_count": null, "id": "bf46b55b", "metadata": {}, "outputs": [], "source": [ "# Plotly version\n", "print(\"Plotly output (interactive - try zooming!):\")\n", "fig_plotly = plotter(bp_complex, backend=\"plotly\")\n", "fig_plotly.update_layout(title=\"Complex Pulse - Plotly (Interactive)\")\n", "fig_plotly.show()" ] } ], "metadata": { "kernelspec": { "display_name": ".conda", "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.12.12" } }, "nbformat": 4, "nbformat_minor": 5 }