"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import pandas as pd\n",
"import holoviews as hv\n",
"from holoviews import opts\n",
"\n",
"hv.extension('matplotlib')\n",
"\n",
"hv.output(fig='svg')\n",
"opts.defaults(opts.HeatMap(fig_size=250))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A radial ``HeatMap`` is well suited to discover **periodic patterns** and **trends** in **time series** data and other cyclic variables. A radial HeatMap can be plotted simply by activating the ``radial`` plot option on the ``HeatMap`` element. \n",
"\n",
"Here we will create a synthetic dataset of a value varying by the hour of the day and day of the week:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"days = 31\n",
"hours = 24\n",
"size = days*hours\n",
"\n",
"def generate_hourly_periodic_data(x):\n",
" periodic_weekly = np.sin(x*2*np.pi / (24*7))\n",
" periodic_daily = np.sin(x*2*np.pi / 24)\n",
" noise = np.random.random(size=x.size) \n",
" return periodic_weekly + periodic_daily + noise\n",
"\n",
"x = np.linspace(0, size, size)\n",
"y = generate_hourly_periodic_data(x)\n",
"\n",
"date_index = pd.date_range(start=\"2017-10-01\", freq=\"h\", periods=size)\n",
"kdim_segment = date_index.strftime(\"%H:%M\")\n",
"kdim_annular = date_index.strftime(\"%A %d\")\n",
"\n",
"df = pd.DataFrame({\"values\": y, \"hour\": kdim_segment, \"day\": kdim_annular}, index=date_index)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"As with a regular ``HeatMap`` the data should consist of two index variables or key dimensions and one or more value dimensions. Here we declare the 'hour' and 'day' as the key dimensions. For a radial HeatMap to make sense the first key dimension, which will correspond to the radial axis, should be periodic. Here the variable is 'hour', starting at midnight at the top:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"hv.HeatMap(df, [\"hour\", \"day\"]).opts(radial=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The resulting plot is quite bare so we may want to customize it, there are a number of things we can do to make the plot clearer:\n",
"\n",
"1. Increase the inner padding with the ``radius_inner`` option.\n",
"2. Increase the number of ticks along the radial axis using ``xticks``\n",
"3. Add radial separator marks with the ``xmarks`` option.\n",
"4. Change the colormap using the ``cmap`` style option."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"hv.HeatMap(df, [\"hour\", \"day\"]).opts(\n",
" opts.HeatMap(cmap='viridis', radial=True, radius_inner=0.2, xmarks=8, xticks=8, ymarks=4))"
]
}
],
"metadata": {
"language_info": {
"name": "python",
"pygments_lexer": "ipython3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}