{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Interactive Plots Integration (Plotly, Bokeh, Highcharts)\n", "\n", "PyBloqs also supports plotting with interactive plotting libraries such as Plotly(offline), Bokeh and Highcharts.\n", "\n", "The plots will be rendered in HTML and will rely on your browser's CSS and JS capabilities to provide interactivity." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Plotly Example" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import plotly.express as px\n", "\n", "df = px.data.gapminder().query(\"country=='Canada'\")\n", "plotly_fig = px.line(df, x=\"year\", y=\"lifeExp\", title='Life expectancy in Canada')\n", "plotly_fig" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "import pybloqs as p\n", "p.Block(plotly_fig)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Bokeh Example" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "from six.moves import zip\n", "from bokeh.plotting import figure as b_fig\n", "# The lines below are only needed for notebook output\n", "from bokeh.io.output import output_notebook\n", "from bokeh.resources import INLINE \n", "output_notebook(resources=INLINE)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "N = 4000\n", "x = np.random.random(size=N) * 100\n", "y = np.random.random(size=N) * 100\n", "radii = np.random.random(size=N) * 1.5\n", "colors2 = [\"#%02x%02x%02x\" % (int(r), int(g), 150) for r, g in zip(50+2*x, 30+2*y)]\n", "bokeh_fig = b_fig(width=300, height=300)\n", "bokeh_fig.scatter(x,y, radius=radii, fill_color=colors2, fill_alpha=0.6, line_color=None)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "p.Block(bokeh_fig)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Combining Bokeh and Plotly plots with HStack" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "p.HStack([p.Block(bokeh_fig), p.Block(plotly_fig)])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Highcharts examples\n", "Please note: Highcharts has a [proprietary license](https://shop.highsoft.com/highcharts-t2)\n", "\n", "#### Simple line chart\n", "When evaluated as the last expression in a Notebook Cell, the plot is automatically displayed inline.\n", "Note how the plot name (hover over the line to see the little popup) is taken from the input data (if available)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "import numpy as np\n", "from datetime import datetime\n", "\n", "df = pd.DataFrame((np.random.rand(200, 4)-0.5)/10,\n", " columns=list(\"ABCD\"),\n", " index=pd.date_range(datetime(2000,1,1), periods=200))\n", "df_cr = (df + 1).cumprod()\n", "a = df_cr['A']\n", "b = df_cr['B']\n", "c = df_cr['C']" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import pybloqs.plot as pp\n", "pp.interactive()\n", "pp.Plot(a)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Saving as interactive HTML" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pp.Plot(df).save(\"chart_sample.html\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Scatter Plot\n", "Regular scatter plot, with zooming on both the x and y axes." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pp.Plot(df.values[:,:2], pp.Scatter(pp.Marker(enabled=True)), pp.Chart(zoom_type=\"xy\"))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Bar Charts \n", "Notice how when viewing all the data at once, the chart shows monthly data, yet zooming in reveals additional detail at up to daily resolution. This is accomplished by using a custom data grouping." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "bar_grouping = pp.DataGrouping(approximation=\"open\", enabled=True, group_pixel_width=100)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Bar chart from a dataframe\n", "pp.Plot(df, pp.Column(bar_grouping))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Stacked bar chart\n", "pp.Plot(df, pp.Column(bar_grouping, stacking=\"normal\"))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Composite bar chart from two separate plots.\n", "s2 = pp.Plot([pp.Plot(a, pp.Column(bar_grouping)),\n", " pp.Plot(b, pp.Column(bar_grouping))])\n", "s2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Comparing series in a dataframe\n", "\n", "Plot the cumulative percentage difference between input series (or columns of a dataframe). The cumulative difference is always calculated from the start of the observation window. This results in intuitively correct behavior when zooming in or sliding the window, as the chart will dynamically recalculate the values. Incredibly useful for comparing model performance over time for example as one doesn't need to manually normalize money curves for different periods.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s3 = pp.Plot(df_cr,\n", " pp.PlotOptions(pp.Series(compare=\"percent\")),\n", " pp.TooltipPct(),\n", " pp.YAxisPct())\n", "s3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Three series on separate side-by-side Y axes" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s4 = pp.Plot([pp.Plot(a),\n", " pp.Plot(b, pp.YAxis(pp.Title(text=\"B Axis\"), opposite=True)),\n", " pp.Plot(c, pp.YAxis(pp.Title(text=\"C Axis\"), opposite=True, offset=40))])\n", "s4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Two series on separate subplots" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s5 = pp.Plot([pp.Plot(a, pp.Line(), pp.YAxis(pp.Title(text=\"a only\"), height=150)),\n", " pp.Plot(b, pp.Column(), pp.YAxis(pp.Title(text=\"b only\"),\n", " top=200, height=100, offset=0))],\n", " pp.Tooltip(value_decimals=2), height=\"400px\")\n", "s5" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Creating a report from multiple charts and saving as HTML or PDF. Or sending it as email." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import pandas.util.testing as pt\n", "b = p.Block([p.Block(pt.makeTimeDataFrame().tail(10), title=\"A table\", title_level=1),\n", " p.Block([s2, s3], title=\"Side-by-side Plots\", cols=2),\n", " p.Block(title=\"Full Width Plots\", styles={\"page-break-before\": \"always\"}),\n", " p.Block(s4, title=\"Side by Side Axes\"),\n", " p.Block(s5, title=\"Composite Plots\")], title=\"Dynamic Reports\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "b.save(\"charts_test.pdf\")\n", "b.save(\"charts_test.html\")" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "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 }