{ "cells": [ { "cell_type": "markdown", "metadata": { "toc": true }, "source": [ "<h1>Table of Contents<span class=\"tocSkip\"></span></h1>\n", "<div class=\"toc\" style=\"margin-top: 1em;\"><ul class=\"toc-item\"><li><span><a href=\"#Chart-object\" data-toc-modified-id=\"Chart-object-1\"><span class=\"toc-item-num\">1 </span>Chart object</a></span></li><li><span><a href=\"#Adding-chart-labels\" data-toc-modified-id=\"Adding-chart-labels-2\"><span class=\"toc-item-num\">2 </span>Adding chart labels</a></span></li><li><span><a href=\"#Getting-help\" data-toc-modified-id=\"Getting-help-3\"><span class=\"toc-item-num\">3 </span>Getting help</a></span></li><li><span><a href=\"#Callouts\" data-toc-modified-id=\"Callouts-4\"><span class=\"toc-item-num\">4 </span>Callouts</a></span></li><li><span><a href=\"#Axes\" data-toc-modified-id=\"Axes-5\"><span class=\"toc-item-num\">5 </span>Axes</a></span></li><li><span><a href=\"#Method-chaining\" data-toc-modified-id=\"Method-chaining-6\"><span class=\"toc-item-num\">6 </span>Method chaining</a></span></li><li><span><a href=\"#Plotting\" data-toc-modified-id=\"Plotting-7\"><span class=\"toc-item-num\">7 </span>Plotting</a></span><ul class=\"toc-item\"><li><span><a href=\"#Input-data-format\" data-toc-modified-id=\"Input-data-format-7.1\"><span class=\"toc-item-num\">7.1 </span>Input data format</a></span></li><li><span><a href=\"#Pivoted-data:-INVALID\" data-toc-modified-id=\"Pivoted-data:-INVALID-7.2\"><span class=\"toc-item-num\">7.2 </span>Pivoted data: INVALID</a></span><ul class=\"toc-item\"><li><span><a href=\"#Melting-pivoted-data:-VALID\" data-toc-modified-id=\"Melting-pivoted-data:-VALID-7.2.1\"><span class=\"toc-item-num\">7.2.1 </span>Melting pivoted data: VALID</a></span></li></ul></li><li><span><a href=\"#Pandas-series:-INVALID\" data-toc-modified-id=\"Pandas-series:-INVALID-7.3\"><span class=\"toc-item-num\">7.3 </span>Pandas series: INVALID</a></span></li><li><span><a href=\"#Pandas-index:-INVALID\" data-toc-modified-id=\"Pandas-index:-INVALID-7.4\"><span class=\"toc-item-num\">7.4 </span>Pandas index: INVALID</a></span></li><li><span><a href=\"#Pandas-DataFrame:-VALID\" data-toc-modified-id=\"Pandas-DataFrame:-VALID-7.5\"><span class=\"toc-item-num\">7.5 </span>Pandas DataFrame: VALID</a></span></li></ul></li><li><span><a href=\"#Axis-types\" data-toc-modified-id=\"Axis-types-8\"><span class=\"toc-item-num\">8 </span>Axis types</a></span></li><li><span><a href=\"#Vertical-Bar-plot\" data-toc-modified-id=\"Vertical-Bar-plot-9\"><span class=\"toc-item-num\">9 </span>Vertical Bar plot</a></span></li><li><span><a href=\"#Examples\" data-toc-modified-id=\"Examples-10\"><span class=\"toc-item-num\">10 </span>Examples</a></span></li><li><span><a href=\"#Bar-plot---Horizontal-vs.-Vertical\" data-toc-modified-id=\"Bar-plot---Horizontal-vs.-Vertical-11\"><span class=\"toc-item-num\">11 </span>Bar plot - Horizontal vs. Vertical</a></span></li><li><span><a href=\"#Grouped-bar-plot\" data-toc-modified-id=\"Grouped-bar-plot-12\"><span class=\"toc-item-num\">12 </span>Grouped bar plot</a></span></li><li><span><a href=\"#show('html')-vs.-show('png')\" data-toc-modified-id=\"show('html')-vs.-show('png')-13\"><span class=\"toc-item-num\">13 </span>show('html') vs. show('png')</a></span></li><li><span><a href=\"#Color-palette-types\" data-toc-modified-id=\"Color-palette-types-14\"><span class=\"toc-item-num\">14 </span>Color palette types</a></span></li><li><span><a href=\"#Color-palettes\" data-toc-modified-id=\"Color-palettes-15\"><span class=\"toc-item-num\">15 </span>Color palettes</a></span></li><li><span><a href=\"#Layouts\" data-toc-modified-id=\"Layouts-16\"><span class=\"toc-item-num\">16 </span>Layouts</a></span></li><li><span><a href=\"#Advanced-usage-with-Bokeh\" data-toc-modified-id=\"Advanced-usage-with-Bokeh-17\"><span class=\"toc-item-num\">17 </span>Advanced usage with Bokeh</a></span></li></ul></div>" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Copyright (c) 2017-2018 Spotify AB\n", "#\n", "# Licensed under the Apache License, Version 2.0 (the \"License\");\n", "# you may not use this file except in compliance with the License.\n", "# You may obtain a copy of the License at\n", "#\n", "# http://www.apache.org/licenses/LICENSE-2.0\n", "#\n", "# Unless required by applicable law or agreed to in writing, software\n", "# distributed under the License is distributed on an \"AS IS\" BASIS,\n", "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", "# See the License for the specific language governing permissions and\n", "# limitations under the License.\n", "import chartify\n", "import pandas as pd\n", "\n", "def print_public_methods(obj):\n", " print('Methods:')\n", " print('\\n'.join([x for x in dir(obj) if not x.startswith('_')]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Chart object\n", "- Run the cell below to instantiate a chart and assign to a variable" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ch = chartify.Chart()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Use .show() to render the chart." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ch.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Note that the chart is blank at this point.\n", "- The default labels provide directions for how to override their values." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Adding chart labels\n", "- __Your turn__: Add labels to the following chart. Look at the default values for instruction.\n", "- Title\n", "- Subtitle\n", "- Source\n", "- X label\n", "- Y label" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ch = chartify.Chart()\n", "# Add code here to overwrite the labels\n", "\n", "\n", "ch.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Getting help\n", "- From within a jupyter notebook you can see the available attributes of the chart object by pressing \"tab\"\n", "- Select the space just after the \".\" character below and hit tab." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ch = chartify.Chart()\n", "ch." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- You can also use \"?\" to pull up documentation for objects and methods.\n", "- Run the cell below to pull up the chartify.Chart documentation" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "chartify.Chart?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- This can also be accomplished by pressing \"shift + tab\".\n", "- Press \"shift + tab\" twice to see the expanded documentation.\n", "- Try it with the next cell." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "chartify.Chart" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Callouts\n", "- The chart object has a callout object (ch.callout) that contains methods for adding callouts to the chart.\n", "- Callouts can be used to add text, lines, or shaded areas to annotate parts of your chart.\n", "- __Your Turn:__ Fill in the code below to add a text callout that says \"hi\" at coordinate (10, 10)\n", "- Look up the documentation for ch.callout.text if you need help" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ch = chartify.Chart()\n", "ch.callout.text(# Fill in the code here)\n", " \n", "ch.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Use tab below to see what callouts are available." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ch.callout." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- You should see this list of callouts:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# List of available callouts:\n", "print_public_methods(ch.callout)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Axes\n", "- The axes object contains methods for setting or getting axis properties." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Avaiable axes methods:\n", "print_public_methods(ch.axes)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- __Your turn__: modify the chart below so the xaxis range goes from 0 to 100" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ch = chartify.Chart()\n", "ch.callout.text('hi', 10, 10)\n", "# Add code here to modify the xrange to (0, 100)\n", "ch.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Method chaining\n", "- Chart methods can be chained by wrapping the statments in parentheses. See the example below:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "(chartify.Chart(blank_labels=True)\n", " .callout.text('hi', 10, 10)\n", " .axes.set_xaxis_range(0, 100)\n", " .show()\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Plotting" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Input data format\n", "Chartify expects the input data to be:\n", "- Tidy (Each variable has its own column, each row corresponds to an observation)\n", "- In the columns of a Pandas DataFrame.\n", "\n", "Below we'll explore some examples of valid and invalid input data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Run this cell to generate an example dataset" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "data = chartify.examples.example_data()\n", "data.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Pivoted data: INVALID\n", "- Pivoted data is not Tidy (note the `country` dimension has an observation in each column)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pivoted_data = pd.pivot_table(data, columns='country', values='quantity', index='fruit', aggfunc='sum')\n", "pivoted_data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Melting pivoted data: VALID\n", "- You can use pandas.melt to convert pivoted data into the tidy data format.\n", "- The output of SQL queries with `groupby` produces output in tidy format." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "value_columns = pivoted_data.columns\n", "\n", "melted_data = pd.melt(pivoted_data.reset_index(), # Need to reset the index to put \"fruit\" into a column.\n", " id_vars='fruit',\n", " value_vars=value_columns)\n", "melted_data.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Pandas series: INVALID\n", "- Data in a pandas Series must be converted to a DataFrame for use with Chartify." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "data.groupby(['country'])['quantity'].sum()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Pandas index: INVALID\n", "- The output below is a pandas DataFrame, but the country dimension is in the Index." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "data.groupby(['country'])[['quantity']].sum()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Pandas DataFrame: VALID\n", "- The code below produces a valid pandas DataFrame for use with Chartify.\n", "- Notice how the country dimension is now in a column." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "chart_data = data.groupby(['country'])['quantity'].sum().reset_index()\n", "chart_data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Axis types\n", "- Specify the x_axis_type and y_axis_type parameters when instantiating the chart object.\n", "- Both are set to `linear` by default.\n", "- Look at the chart object documentation to see the list of available options for x_axis_type and y_axis_type" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "chartify.Chart?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- __The Chart axis types influence the plots that are available__\n", "- Look at how the plot methods change based on the axis types:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ch = chartify.Chart(x_axis_type='datetime',\n", " y_axis_type='linear')\n", "# List of available callouts:\n", "print_public_methods(ch.plot)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ch = chartify.Chart(x_axis_type='categorical',\n", " y_axis_type='linear')\n", "# List of available plots:\n", "print_public_methods(ch.plot)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- __Your turn__: Create a chart with 'density' y and 'linear' x axis types. What type of plots are available?" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ch = chartify.Chart(# Your code goes here)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Vertical Bar plot\n", "- __Your turn__: Create a bar plot based on the dataframe below." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "bar_data = (data.groupby('country')[['quantity']].sum()\n", " .reset_index()\n", " )\n", "bar_data" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Implement the bar plot here.\n", "# Set the appropriate x_axis_type otherwise the bar method won't be available.\n", "# Look at the bar documentation to figure out how to pass in the parameters.\n", "# If you get stuck move on to the next section for hints.\n", "ch = chartify.Chart(# Your code goes here)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Examples\n", "- Chartify includes many examples. They're a good starting point if you're trying to create a chart that you're unfamiliar with." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# List of available examples\n", "print_public_methods(chartify.examples)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Run the appropriate method to see examples and the corresponding code that generates the example." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "chartify.examples.plot_bar()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Bar plot - Horizontal vs. Vertical\n", "- Copy your bar plot here, but make it horizantal instead of vertical. Look to the example above if you get stuck." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Grouped bar plot\n", "- __Your Turn__: Create a grouped bar plot with the data below." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "grouped_bar_data = (data.groupby(['country', 'fruit'])[['quantity']].sum()\n", " .reset_index()\n", " )\n", "grouped_bar_data" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Implement the grouped bar plot here.\n", "# Look at the example for help if you get stuck.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# show('html') vs. show('png')\n", "- Chartify charts can be rendered as either \"HTML\" or \"PNG\" (HTML is the default)\n", "- HTML output:\n", " - Is faster and good for iteration.\n", " - Can be saved as an image by screenshotting, or by clicking the icon on the top right.\n", " - Will _NOT_ show up in Jupyter notebooks when uploaded to GHE.\n", "- PNG output:\n", " - Is slower and better for the finished product.\n", " - Can be copy and pasted directly from the jupyter notebook (Right click on the image)\n", " - Will show up in Jupyter notebooks when uploaded to GHE.\n", "- See the difference by running the two cells below" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "(chartify.Chart(blank_labels=True)\n", ".set_title(\"HTML output\")\n", ".set_subtitle(\"Faster, but will not show up in GHE\")\n", ".show()\n", ")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "(chartify.Chart(blank_labels=True)\n", ".set_title(\"PNG output\")\n", ".set_subtitle(\"Slower, but will show up in GHE. Right click to copy + paste.\")\n", ".show('png')\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Color palette types\n", "- Chartify includes 4 different color palette types: `categorical`, `accent`, `sequential`, `diverging`.\n", "- Note the differences in the examples below" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "chartify.examples.style_color_palette_categorical()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "chartify.examples.style_color_palette_accent()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "chartify.examples.style_color_palette_diverging()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "chartify.examples.style_color_palette_sequential()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Color palettes\n", "- Chartify includes a set of pre-defined color palettes:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "chartify.color_palettes" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Use .show() to see the colors associated with each:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "chartify.color_palettes.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Assign the color palettes with `.set_color_palette`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ch = chartify.Chart(x_axis_type='categorical',\n", " blank_labels=True)\n", "ch.style.set_color_palette('categorical', 'Dark2')\n", "ch.plot.bar(data_frame=grouped_bar_data,\n", " categorical_columns=['fruit', 'country'],\n", " numeric_column='quantity',\n", " color_column='fruit')\n", "ch.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Color palette objects include methods for manipulation. See the examples below:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "dark2 = chartify.color_palettes['Dark2']\n", "dark2.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Sort" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sorted_dark2 = dark2.sort_by_hue()\n", "sorted_dark2.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Expand" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "dark2.expand_palette(20).show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Shift" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "shifted_dark2 = dark2.shift_palette('white', percent=20)\n", "shifted_dark2.show()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "- Assign the shifted color palette to a chart:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ch = chartify.Chart(x_axis_type='categorical',\n", " blank_labels=True)\n", "ch.style.set_color_palette('categorical', shifted_dark2)\n", "ch.plot.bar(data_frame=grouped_bar_data,\n", " categorical_columns=['fruit', 'country'],\n", " numeric_column='quantity',\n", " color_column='fruit')\n", "ch.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Layouts\n", "- Chartify layouts are tailored toward use in slides.\n", "- Notice how the output changes for each of the slide layout options below:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "layout_options = ['slide_100%', 'slide_75%', 'slide_50%', 'slide_25%']\n", "for option in layout_options:\n", " ch = chartify.Chart(layout=option, blank_labels=True, x_axis_type='categorical')\n", " ch.set_title('Layout: {}'.format(option))\n", " ch.plot.bar(data_frame=grouped_bar_data,\n", " categorical_columns=['fruit', 'country'],\n", " numeric_column='quantity',\n", " color_column='fruit')\n", "\n", " ch.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Advanced usage with Bokeh\n", "- Chartify is built on top of another visualization package called [Bokeh](http://bokeh.pydata.org/en/latest/)\n", "- The example below shows how you can access the Bokeh [figure](https://bokeh.pydata.org/en/latest/docs/reference/plotting.html#bokeh.plotting.figure.Figure) from a Chartify chart object." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ch = chartify.Chart(blank_labels=True, x_axis_type='categorical')\n", "ch.plot.bar(data_frame=grouped_bar_data,\n", " categorical_columns=['fruit', 'country'],\n", " numeric_column='quantity',\n", " color_column='fruit')\n", "ch.figure" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- The following example shows how you can modify attributes not exposed in Chartify by accessing the Bokeh figure. See [Bokeh](http://bokeh.pydata.org/en/latest/) documentation for more details." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ch.figure.xaxis.axis_label_text_font_size = '30pt'\n", "ch.figure.xaxis.axis_label_text_color = 'red'\n", "ch.figure.height = 400\n", "ch.axes.set_xaxis_label('A large xaxis label')\n", "ch.show()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "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.8.13" }, "toc": { "nav_menu": {}, "number_sections": true, "sideBar": true, "skip_h1_title": false, "toc_cell": true, "toc_position": { "height": "608px", "left": "0px", "right": "1176px", "top": "111px", "width": "212px" }, "toc_section_display": "block", "toc_window_display": true } }, "nbformat": 4, "nbformat_minor": 4 }