|
90 | 90 | "\n", |
91 | 91 | "get_ipython().display_formatter.formatters[\"image/png\"].for_type(\n", |
92 | 92 | " lp.plot.core.PlotSpec, _lets_plot_png\n", |
| 93 | + ")\n", |
| 94 | + "\n", |
| 95 | + "import atexit\n", |
| 96 | + "import io\n", |
| 97 | + "import logging\n", |
| 98 | + "\n", |
| 99 | + "import holoviews as hv\n", |
| 100 | + "import hvplot.pandas # registers the .hvplot accessor on pandas objects\n", |
| 101 | + "from bokeh.io.export import get_screenshot_as_png\n", |
| 102 | + "from bokeh.models import Plot\n", |
| 103 | + "\n", |
| 104 | + "hv.extension(\"bokeh\")\n", |
| 105 | + "logging.getLogger(\"bokeh.io.export\").setLevel(logging.ERROR)\n", |
| 106 | + "hv.plotting.bokeh.ElementPlot.toolbar = None\n", |
| 107 | + "hv.plotting.bokeh.ElementPlot.fontscale = 1.6\n", |
| 108 | + "\n", |
| 109 | + "_bokeh_driver = None\n", |
| 110 | + "\n", |
| 111 | + "\n", |
| 112 | + "def _bokeh_webdriver():\n", |
| 113 | + " \"\"\"Headless Chrome for Bokeh's PNG export.\n", |
| 114 | + "\n", |
| 115 | + " Bokeh screenshots plots through Selenium. Reuse the Chrome for Testing\n", |
| 116 | + " build Kaleido already downloads; Selenium Manager supplies the matching\n", |
| 117 | + " chromedriver.\n", |
| 118 | + " \"\"\"\n", |
| 119 | + " global _bokeh_driver\n", |
| 120 | + " if _bokeh_driver is None:\n", |
| 121 | + " from selenium.webdriver.chrome.options import Options\n", |
| 122 | + " from selenium.webdriver.chrome.webdriver import WebDriver as Chrome\n", |
| 123 | + "\n", |
| 124 | + " options = Options()\n", |
| 125 | + " options.add_argument(\"--headless=new\")\n", |
| 126 | + " options.add_argument(\"--hide-scrollbars\")\n", |
| 127 | + " options.add_argument(\"--force-device-scale-factor=1\")\n", |
| 128 | + " options.add_argument(\"--force-color-profile=srgb\")\n", |
| 129 | + " options.add_argument(\"--no-sandbox\")\n", |
| 130 | + " try:\n", |
| 131 | + " from choreographer.browsers.chromium import Chromium\n", |
| 132 | + "\n", |
| 133 | + " options.binary_location = str(Chromium.find_browser(skip_local=False))\n", |
| 134 | + " except Exception: # fall back to whatever Chrome is on the system\n", |
| 135 | + " pass\n", |
| 136 | + " _bokeh_driver = Chrome(options=options)\n", |
| 137 | + " atexit.register(_bokeh_driver.quit)\n", |
| 138 | + " return _bokeh_driver\n", |
| 139 | + "\n", |
| 140 | + "\n", |
| 141 | + "def _hvplot_png(obj):\n", |
| 142 | + " \"\"\"Render an hvPlot/HoloViews Bokeh figure to PNG for the cell output.\"\"\"\n", |
| 143 | + " figure = hv.render(obj, backend=\"bokeh\")\n", |
| 144 | + " models = figure.references()\n", |
| 145 | + " for model in models:\n", |
| 146 | + " if \"toolbar_location\" in model.properties():\n", |
| 147 | + " model.toolbar_location = None\n", |
| 148 | + " panes = [m for m in models if isinstance(m, Plot)]\n", |
| 149 | + " if len(panes) == 1: # leave faceted grids at their per-panel size\n", |
| 150 | + " panes[0].width, panes[0].height = 750, 750\n", |
| 151 | + " image = get_screenshot_as_png(figure, driver=_bokeh_webdriver())\n", |
| 152 | + " buffer = io.BytesIO()\n", |
| 153 | + " image.save(buffer, format=\"png\")\n", |
| 154 | + " return buffer.getvalue()\n", |
| 155 | + "\n", |
| 156 | + "\n", |
| 157 | + "get_ipython().display_formatter.formatters[\"image/png\"].for_type(\n", |
| 158 | + " hv.core.dimension.Dimensioned, _hvplot_png\n", |
93 | 159 | ")" |
94 | 160 | ] |
95 | 161 | }, |
|
397 | 463 | " .label(title=\"Number of Cars by Make\"))" |
398 | 464 | ] |
399 | 465 | }, |
| 466 | + { |
| 467 | + "cell_type": "code", |
| 468 | + "execution_count": null, |
| 469 | + "metadata": { |
| 470 | + "tags": [ |
| 471 | + "ex", |
| 472 | + "name:bar-counts", |
| 473 | + "package:hvplot" |
| 474 | + ] |
| 475 | + }, |
| 476 | + "outputs": [], |
| 477 | + "source": [ |
| 478 | + "\"\"\"hvPlot exposes Bokeh through a `.hvplot`\n", |
| 479 | + "accessor that mirrors pandas' own `.plot`.\n", |
| 480 | + "\"\"\"\n", |
| 481 | + "(mpg[\"manufacturer\"]\n", |
| 482 | + " .value_counts(sort=False)\n", |
| 483 | + " .hvplot.barh(\n", |
| 484 | + " title=\"Number of Cars by Make\"))" |
| 485 | + ] |
| 486 | + }, |
400 | 487 | { |
401 | 488 | "cell_type": "markdown", |
402 | 489 | "metadata": {}, |
|
545 | 632 | " .add(so.Bars(), so.Hist(binwidth=2)))" |
546 | 633 | ] |
547 | 634 | }, |
| 635 | + { |
| 636 | + "cell_type": "code", |
| 637 | + "execution_count": null, |
| 638 | + "metadata": { |
| 639 | + "tags": [ |
| 640 | + "ex", |
| 641 | + "name:simple-histogram", |
| 642 | + "package:hvplot" |
| 643 | + ] |
| 644 | + }, |
| 645 | + "outputs": [], |
| 646 | + "source": [ |
| 647 | + "mpg.hvplot.hist(\"cty\", bins=12)" |
| 648 | + ] |
| 649 | + }, |
548 | 650 | { |
549 | 651 | "cell_type": "markdown", |
550 | 652 | "metadata": {}, |
|
700 | 802 | " title=\"Engine Displacement in Liters vs Highway MPG\"))" |
701 | 803 | ] |
702 | 804 | }, |
| 805 | + { |
| 806 | + "cell_type": "code", |
| 807 | + "execution_count": null, |
| 808 | + "metadata": { |
| 809 | + "tags": [ |
| 810 | + "ex", |
| 811 | + "name:scatter-plot", |
| 812 | + "package:hvplot" |
| 813 | + ] |
| 814 | + }, |
| 815 | + "outputs": [], |
| 816 | + "source": [ |
| 817 | + "mpg.hvplot.scatter(\n", |
| 818 | + " x=\"displ\", y=\"hwy\",\n", |
| 819 | + " xlabel=\"Engine Displacement in Liters\",\n", |
| 820 | + " ylabel=\"Highway MPG\",\n", |
| 821 | + " title=\"Engine Displacement in Liters \"\n", |
| 822 | + " \"vs Highway MPG\")" |
| 823 | + ] |
| 824 | + }, |
703 | 825 | { |
704 | 826 | "cell_type": "markdown", |
705 | 827 | "metadata": {}, |
|
1043 | 1165 | ")" |
1044 | 1166 | ] |
1045 | 1167 | }, |
| 1168 | + { |
| 1169 | + "cell_type": "code", |
| 1170 | + "execution_count": null, |
| 1171 | + "metadata": { |
| 1172 | + "tags": [ |
| 1173 | + "ex", |
| 1174 | + "name:scatter-plot-with-colors", |
| 1175 | + "package:hvplot" |
| 1176 | + ] |
| 1177 | + }, |
| 1178 | + "outputs": [], |
| 1179 | + "source": [ |
| 1180 | + "mpg.hvplot.scatter(\n", |
| 1181 | + " x=\"displ\", y=\"hwy\", by=\"class\")" |
| 1182 | + ] |
| 1183 | + }, |
1046 | 1184 | { |
1047 | 1185 | "cell_type": "markdown", |
1048 | 1186 | "metadata": {}, |
|
1199 | 1337 | " .label(x=\"City MPG\", y=\"Highway MPG\"))" |
1200 | 1338 | ] |
1201 | 1339 | }, |
| 1340 | + { |
| 1341 | + "cell_type": "code", |
| 1342 | + "execution_count": null, |
| 1343 | + "metadata": { |
| 1344 | + "tags": [ |
| 1345 | + "ex", |
| 1346 | + "name:scatter-plot-with-size", |
| 1347 | + "package:hvplot" |
| 1348 | + ] |
| 1349 | + }, |
| 1350 | + "outputs": [], |
| 1351 | + "source": [ |
| 1352 | + "mpg.hvplot.scatter(\n", |
| 1353 | + " x=\"cty\", y=\"hwy\",\n", |
| 1354 | + " s=\"cyl\", scale=4, alpha=0.5)" |
| 1355 | + ] |
| 1356 | + }, |
1202 | 1357 | { |
1203 | 1358 | "cell_type": "markdown", |
1204 | 1359 | "metadata": {}, |
|
1338 | 1493 | ")" |
1339 | 1494 | ] |
1340 | 1495 | }, |
| 1496 | + { |
| 1497 | + "cell_type": "code", |
| 1498 | + "execution_count": null, |
| 1499 | + "metadata": { |
| 1500 | + "tags": [ |
| 1501 | + "ex", |
| 1502 | + "name:scatter-plot-with-facet", |
| 1503 | + "package:hvplot" |
| 1504 | + ] |
| 1505 | + }, |
| 1506 | + "outputs": [], |
| 1507 | + "source": [ |
| 1508 | + "(mpg.hvplot.scatter(\n", |
| 1509 | + " x=\"displ\", y=\"hwy\", by=\"class\",\n", |
| 1510 | + " subplots=True, fontscale=0.65,\n", |
| 1511 | + " width=185, height=185)\n", |
| 1512 | + " .cols(4))" |
| 1513 | + ] |
| 1514 | + }, |
1341 | 1515 | { |
1342 | 1516 | "cell_type": "markdown", |
1343 | 1517 | "metadata": {}, |
|
1482 | 1656 | ")" |
1483 | 1657 | ] |
1484 | 1658 | }, |
| 1659 | + { |
| 1660 | + "cell_type": "code", |
| 1661 | + "execution_count": null, |
| 1662 | + "metadata": { |
| 1663 | + "tags": [ |
| 1664 | + "ex", |
| 1665 | + "name:scatter-plot-with-facets", |
| 1666 | + "package:hvplot" |
| 1667 | + ] |
| 1668 | + }, |
| 1669 | + "outputs": [], |
| 1670 | + "source": [ |
| 1671 | + "\"\"\"`row` and `col` build a HoloViews `GridSpace`,\n", |
| 1672 | + "which sorts its panels by the facet values.\n", |
| 1673 | + "\"\"\"\n", |
| 1674 | + "mpg.hvplot.scatter(\n", |
| 1675 | + " x=\"displ\", y=\"hwy\",\n", |
| 1676 | + " row=\"cyl\", col=\"drv\", subplots=True,\n", |
| 1677 | + " fontscale=0.8, width=230, height=180)" |
| 1678 | + ] |
| 1679 | + }, |
1485 | 1680 | { |
1486 | 1681 | "cell_type": "markdown", |
1487 | 1682 | "metadata": {}, |
|
1778 | 1973 | " .add(so.Bar(), so.Count(), so.Stack()))" |
1779 | 1974 | ] |
1780 | 1975 | }, |
| 1976 | + { |
| 1977 | + "cell_type": "code", |
| 1978 | + "execution_count": null, |
| 1979 | + "metadata": { |
| 1980 | + "tags": [ |
| 1981 | + "ex", |
| 1982 | + "name:stacked-bar-chart", |
| 1983 | + "package:hvplot" |
| 1984 | + ] |
| 1985 | + }, |
| 1986 | + "outputs": [], |
| 1987 | + "source": [ |
| 1988 | + "(diamonds\n", |
| 1989 | + " .groupby([\"cut\", \"clarity\"])\n", |
| 1990 | + " .size()\n", |
| 1991 | + " .unstack()\n", |
| 1992 | + " .hvplot.bar(stacked=True, rot=45,\n", |
| 1993 | + " legend=\"top_left\"))" |
| 1994 | + ] |
| 1995 | + }, |
1781 | 1996 | { |
1782 | 1997 | "cell_type": "code", |
1783 | 1998 | "execution_count": null, |
|
1907 | 2122 | " .add(so.Bar(), so.Count(), so.Dodge()))" |
1908 | 2123 | ] |
1909 | 2124 | }, |
| 2125 | + { |
| 2126 | + "cell_type": "code", |
| 2127 | + "execution_count": null, |
| 2128 | + "metadata": { |
| 2129 | + "tags": [ |
| 2130 | + "ex", |
| 2131 | + "name:dodged-bar-chart", |
| 2132 | + "package:hvplot" |
| 2133 | + ] |
| 2134 | + }, |
| 2135 | + "outputs": [], |
| 2136 | + "source": [ |
| 2137 | + "(diamonds\n", |
| 2138 | + " .groupby([\"cut\", \"clarity\"])\n", |
| 2139 | + " .size()\n", |
| 2140 | + " .unstack()\n", |
| 2141 | + " .hvplot.bar(stacked=False, rot=45,\n", |
| 2142 | + " legend=\"top_left\"))" |
| 2143 | + ] |
| 2144 | + }, |
1910 | 2145 | { |
1911 | 2146 | "cell_type": "code", |
1912 | 2147 | "execution_count": null, |
|
2072 | 2307 | "Image(fig.to_image(format=\"png\", width=750, height=750))" |
2073 | 2308 | ] |
2074 | 2309 | }, |
| 2310 | + { |
| 2311 | + "cell_type": "code", |
| 2312 | + "execution_count": null, |
| 2313 | + "metadata": { |
| 2314 | + "tags": [ |
| 2315 | + "ex", |
| 2316 | + "name:stacked-kde", |
| 2317 | + "package:hvplot" |
| 2318 | + ] |
| 2319 | + }, |
| 2320 | + "outputs": [], |
| 2321 | + "source": [ |
| 2322 | + "\"\"\"`xlim` only clips the axis. Unlike ggplot2's\n", |
| 2323 | + "`xlim()` it doesn't drop rows before the\n", |
| 2324 | + "densities are estimated.\n", |
| 2325 | + "\"\"\"\n", |
| 2326 | + "diamonds.hvplot.kde(\n", |
| 2327 | + " y=\"depth\", by=\"cut\",\n", |
| 2328 | + " alpha=0.1, xlim=(55, 70))" |
| 2329 | + ] |
| 2330 | + }, |
2075 | 2331 | { |
2076 | 2332 | "cell_type": "code", |
2077 | 2333 | "execution_count": null, |
|
2186 | 2442 | "(so.Plot(ts, x=\"date\", y=\"value\")\n", |
2187 | 2443 | " .add(so.Line()))" |
2188 | 2444 | ] |
| 2445 | + }, |
| 2446 | + { |
| 2447 | + "cell_type": "code", |
| 2448 | + "execution_count": null, |
| 2449 | + "metadata": { |
| 2450 | + "tags": [ |
| 2451 | + "ex", |
| 2452 | + "name:timeseries", |
| 2453 | + "package:hvplot" |
| 2454 | + ] |
| 2455 | + }, |
| 2456 | + "outputs": [], |
| 2457 | + "source": [ |
| 2458 | + "ts.hvplot.line(x=\"date\", y=\"value\")" |
| 2459 | + ] |
2189 | 2460 | } |
2190 | 2461 | ], |
2191 | 2462 | "metadata": { |
|
0 commit comments