Skip to content

Instantly share code, notes, and snippets.

@ClaartjeBarkhof
Last active August 25, 2020 13:29
Show Gist options
  • Save ClaartjeBarkhof/908c8d2a398a914b04cbe00ad621191d to your computer and use it in GitHub Desktop.
Save ClaartjeBarkhof/908c8d2a398a914b04cbe00ad621191d to your computer and use it in GitHub Desktop.
Bit data visualisation with Matplotlib
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"metadata": {},
"cell_type": "markdown",
"source": "<!-- <img src=\"Assets/banner.png\"> -->\n<img src=\"https://www.dropbox.com/s/b3iasrh4al96r6z/banner.png?raw=1\">"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "***\n# 0 Install libraries needed to run this Notebook"
},
{
"metadata": {
"code_folding": [
0
],
"trusted": true
},
"cell_type": "code",
"source": "# Uncomment and run this cell if you don't have these already\n# !pip install pandas\n# !pip install matplotlib\n# !pip install numpy\n# !pip install pickle",
"execution_count": 19,
"outputs": []
},
{
"metadata": {},
"cell_type": "markdown",
"source": "***\n# 1 Set-up the Bit style\n\n## 1.1 Move the style sheets into your `.matplotlib` folder\n\nMove the style sheets `bit_light.mplstyle` and `bit_dark.mplstyle` to the `stylelib` directory located in your `.matplotlib` folder. If there is not such a directory, create one. If you don't know where to find your `.matplotlib` folder you can find it by running: "
},
{
"metadata": {
"code_folding": [
0
],
"scrolled": true,
"trusted": true
},
"cell_type": "code",
"source": "# Getting the folder of your .matplotlib folder\n# import matplotlib as mpl; print(mpl.get_configdir())\n\n# Run this line to see whether bit_light and bit_dark now show up in the list of styles.\n# import matplotlib.pyplot as plt\n# plt.style.reload_library()\n# plt.style.available",
"execution_count": 33,
"outputs": []
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## 1.2 Install Bit fonts\nMake sure you have the Bit fonts installed. I added them to the folder for you to install. Alternatively, you can download them from the [Bit Google Drive](https://drive.google.com/drive/u/1/folders/1xzeIhI2yAhqHaqm4qpDM6jxE5PXsdpRv). "
},
{
"metadata": {},
"cell_type": "markdown",
"source": "***\n# 2 Colours\n\nTo easily change colours, you can access them through the dictionary below.\n\n<!-- <img src=\"Assets/colours.png\"> -->\n<img src=\"https://www.dropbox.com/s/yhku9tlfyal3i0n/colours.png?raw=1\">"
},
{
"metadata": {
"code_folding": [
0
],
"trusted": true
},
"cell_type": "code",
"source": "color_dict = {'blue':'#8caadc', \n 'pink':'#fcb1ca', \n 'orange':'#efb116', \n 'dark_blue':'#000563',\n 'green':'#005f32',\n 'red':'#c51914', \n 'sand':'#cec3bc'}",
"execution_count": 34,
"outputs": []
},
{
"metadata": {},
"cell_type": "markdown",
"source": "***\n# 3 Imports & settings"
},
{
"metadata": {
"code_folding": [
0
],
"trusted": true
},
"cell_type": "code",
"source": "# Imports\nimport matplotlib as mpl\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\nimport warnings\nimport sys\nsys.path.append('colourmaps/')\n\n# Settings for viewing, you might want to comment if you don't want to use it\n%config InlineBackend.figure_format = 'retina' # high quality displaying of figures\n%matplotlib inline",
"execution_count": 35,
"outputs": []
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## In case you want to do some extra font tweaking, load them to pass them as arguments"
},
{
"metadata": {
"code_folding": [
0
],
"trusted": true
},
"cell_type": "code",
"source": "# Define fontproperty objects (size is changed later with ._size attribute of the fontproperty object)\npath_century = '/Users/claartje/Library/Fonts/Century-Medium.otf'\ncentury_font = mpl.font_manager.FontProperties(fname=path_century)\ncentury_font._size = 14 # To set its size\n\n# For titles we want to use another \npath_roobert = '/Users/claartje/Library/Fonts/Roobert-Medium.otf'\nroobert_font = mpl.font_manager.FontProperties(fname=path_roobert)\nroobert_font._size = 36\n\n# The Century font gives annoying warnings about missing glyphs, if you want to suppress those:\nwarnings.filterwarnings(\"ignore\", category=RuntimeWarning)",
"execution_count": 36,
"outputs": []
},
{
"metadata": {},
"cell_type": "markdown",
"source": "***\n# 4 Code for some demo plots\n## Demo 1: line plot"
},
{
"metadata": {
"code_folding": [
1
],
"trusted": true
},
"cell_type": "code",
"source": "# Code for demo 1\ndef demo_1(file_name):\n # Create figure\n fig = plt.figure(figsize=(15, 10))\n\n # Add subplot to figure\n ax = fig.add_subplot(111)\n\n # Create some data\n x = np.linspace(0, 4*np.pi, 200)\n\n # Plot data\n for amp in [1.0, 1.5, 2.0, 2.5]:\n ax.plot(x, amp*np.sin(x), label='A = {}'.format(amp), linewidth=1*amp) # first plotting color is blue\n\n # Set axis labels (pass font if you want it in Century)\n ax.set_xlabel('This is the x-axis.', fontproperties=century_font)\n ax.set_ylabel('This is the y-axis.', fontproperties=century_font)\n\n # Add title\n ax.set_title('Some demonstrational sine functions.', y=1.05)\n\n # Ticks (if you want it in Century)\n plt.yticks(fontproperties=century_font); plt.xticks(fontproperties=century_font)\n\n # Add legend, manually set the position to right next to the plot a bit to the top\n ax.legend(loc=(1.02, 0.8))\n\n # Show plot\n plt.tight_layout()\n plt.savefig(file_name, bbox_inches='tight', dpi=300)\n\n # Save fig\n plt.show()",
"execution_count": 37,
"outputs": []
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## Demo 2: 4 subplots"
},
{
"metadata": {
"code_folding": [
1
],
"scrolled": false,
"trusted": true
},
"cell_type": "code",
"source": "# Code for demo 2\ndef demo_2(file_name):\n # Create figure with 4 subplots 2 x 2\n fig, axs = plt.subplots(2, 2, figsize=(18, 12))\n\n # Create some data\n x = np.linspace(0, 4*np.pi, 200)\n\n # First plot: ellipses\n for i, r in enumerate([0.5, 0.9, 1.3, 1.7]):\n axs[0, 0].plot(np.sqrt(r)*np.cos(np.linspace(0, 2*np.pi, 100)), \n np.sqrt(r)*np.sin(np.linspace(0, 2*np.pi, 100)), label='Circle {}'.format(i), \n linewidth=1*(i+1))\n\n # Second plot\n df = pd.DataFrame({\"Group 1\": np.random.randint(2, 50, 10), \"Group 2\": np.random.randint(2, 50, 10)})\n df.plot(ax=axs[1,0], kind='bar')\n\n # Third plot\n n, bins, patches = axs[0, 1].hist(100 + 15 * np.random.randn(437), 50, density=1, \n color=color_dict['pink'], label='Histogram', alpha=0.8)\n y = ((1 / (np.sqrt(2 * np.pi) * 15)) * np.exp(-0.5 * (1 / 15 * (bins - 100))**2))\n axs[0, 1].plot(bins, y, '--', color=color_dict['red'], linewidth=2.5, label='Fitted line')\n\n # Fourth plot\n for mu, sigma, marker in [(-.5, 0.75, 'o'), (0.75, 1., 's')]:\n x, y = np.random.normal(loc=mu, scale=sigma, size=(2, 100))\n axs[1, 1].plot(x, y, ls='none', marker=marker, label='mu: {}, sigma: {}'.format(mu, sigma))\n\n # Add title\n mpl.rcParams['axes.titlesize'] = 28\n axs[0, 0].set_title('First plot: ellipses.', y=1.04)\n axs[1, 0].set_title('Second plot: a bar plot.', y=1.04)\n axs[0, 1].set_title('Third plot: a histogram.', y=1.04)\n axs[1, 1].set_title('Fourth plot: scatter plot.', y=1.04)\n\n # Add legend & axes labels\n for row in range(2):\n for col in range(2):\n axs[row, col].legend(loc=(1.02, 0.7))\n axs[row, col].set_xlabel('This is the x-axis.', fontproperties=century_font)\n axs[row, col].set_ylabel('This is the y-axis.', fontproperties=century_font)\n\n plt.suptitle(\"An example of subplots.\", fontproperties=roobert_font, y=1.06)\n\n # Save plot\n plt.tight_layout()\n plt.savefig(file_name, bbox_inches='tight', dpi=300)\n\n # Show plot\n plt.show()",
"execution_count": 38,
"outputs": []
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## Demo 3: heat maps with custom colour maps"
},
{
"metadata": {
"code_folding": [
1
],
"trusted": true
},
"cell_type": "code",
"source": "# Code for demo 3\ndef demo_3(file_name):\n import pickle\n \n bit_cmap_light = pickle.load(open('colourmaps/bit_cmap_light.pkl', 'rb'))\n bit_cmap_dark = pickle.load(open('colourmaps/bit_cmap_dark.pkl', 'rb'))\n \n fig, axs = plt.subplots(1, 2, figsize=(20, 10), dpi=300)\n\n a = np.random.random((16, 16))\n im0 = axs[0].imshow(a, cmap=bit_cmap_light, interpolation='nearest')\n cb = fig.colorbar(im0, ax=axs[0], shrink=0.75)\n axs[0].set_title('One colour map.', y=1.04)\n cb.outline.set_linewidth(0)\n \n # Plot \n a = np.random.random((16, 16))\n im1 = axs[1].imshow(a, cmap=bit_cmap_dark, interpolation='nearest')\n cb = fig.colorbar(im1, ax=axs[1], shrink=0.75)\n axs[1].set_title('And another one.', y=1.04)\n cb.outline.set_linewidth(0)\n \n # Labels\n for i in range(2):\n axs[i].set_xlabel('This is the x-axis.', fontproperties=century_font)\n axs[i].set_ylabel('This is the y-axis.', fontproperties=century_font)\n \n # Title\n roobert_font._size = 36\n plt.suptitle(\"Two different colour maps in Bit colours.\", y=1.04, fontproperties=roobert_font)\n \n # Save plot\n plt.tight_layout()\n plt.savefig(file_name, bbox_inches='tight', dpi=300)\n\n # Show plot\n plt.show()",
"execution_count": 39,
"outputs": []
},
{
"metadata": {},
"cell_type": "markdown",
"source": "## Demo 4: a radar chart"
},
{
"metadata": {
"code_folding": [
1
],
"trusted": true
},
"cell_type": "code",
"source": "# Code for demo 4\ndef demo_4(file_name):\n from math import pi\n from pylab import rcParams\n rcParams['figure.figsize'] = 10, 10\n\n # Set data\n df = pd.DataFrame({\n 'group': ['A','B','C','D'],\n 'One.': [38, 1.5, 30, 4],\n 'Two.': [29, 10, 9, 34],\n 'Three.': [8, 39, 23, 24],\n 'Five': [7, 31, 33, 14],\n 'Six': [28, 15, 32, 14]\n })\n\n\n # ------- PART 1: Create background\n\n # number of variable\n categories=list(df)[1:]\n N = len(categories)\n\n # What will be the angle of each axis in the plot? (we divide the plot / number of variable)\n angles = [n / float(N) * 2 * pi for n in range(N)]\n angles += angles[:1]\n\n # Initialise the spider plot\n ax = plt.subplot(111, polar=True)\n\n # If you want the first axis to be on top:\n ax.set_theta_offset(pi / 2)\n ax.set_theta_direction(-1)\n\n # Draw one axe per variable + add labels labels yet\n plt.xticks(angles[:-1], categories)\n\n # Draw ylabels\n ax.set_rlabel_position(0)\n plt.yticks([10,20,30], [\"10\",\"20\",\"30\"], color=\"grey\", size=7)\n plt.ylim(0,40)\n\n\n # ------- PART 2: Add plots\n\n # Plot each individual = each line of the data\n # I don't do a loop, because plotting more than 3 groups makes the chart unreadable\n\n # Ind1\n values=df.loc[0].drop('group').values.flatten().tolist()\n values += values[:1]\n ax.plot(angles, values, linewidth=2, linestyle='solid', label=\"Group A\")\n ax.fill(angles, values, color_dict['blue'], alpha=0.3)\n\n # Ind2\n values=df.loc[1].drop('group').values.flatten().tolist()\n values += values[:1]\n ax.plot(angles, values, linewidth=2, linestyle='solid', label=\"Group B\")\n ax.fill(angles, values, color_dict['red'], alpha=0.3)\n\n # Title\n plt.title('A radar plot could look something like this!')\n \n # Add legend\n plt.legend(loc=(1.02, 0.8))\n \n # Save plot\n plt.tight_layout()\n plt.savefig(file_name, bbox_inches='tight', dpi=300)\n\n # Show plot\n plt.show()",
"execution_count": 40,
"outputs": []
},
{
"metadata": {},
"cell_type": "markdown",
"source": "***\n# 5 Let's try them with the light theme\n## But first, let's activate the light theme"
},
{
"metadata": {
"code_folding": [
0
],
"trusted": true
},
"cell_type": "code",
"source": "# Activate the light theme\nplt.style.reload_library()\nplt.style.use('bit_light')",
"execution_count": 41,
"outputs": []
},
{
"metadata": {
"code_folding": [
1
],
"scrolled": false,
"trusted": true
},
"cell_type": "code",
"source": "demo_1(\"Exports/light_demo_1.png\") # <-- If you want vector quality, export as .svg\ndemo_2(\"Exports/light_demo_2.png\")\ndemo_3('Exports/light_demo_3.png')\ndemo_4('Exports/light_demo_4.png')",
"execution_count": 2,
"outputs": []
},
{
"metadata": {},
"cell_type": "markdown",
"source": "# 6 Extra: create your own colour map!"
},
{
"metadata": {
"trusted": true
},
"cell_type": "code",
"source": "# Bonus: create your own cmap with the Python file in this directory\nimport make_cmaps as mc\n\n# Just pass a list of colours to this function from make_cmaps.py\nbit_cmap_dark = mc.make_cmap([color_dict['dark_blue'], color_dict['blue'], color_dict['pink'], color_dict['orange'], color_dict['red']])\nbit_cmap_light = mc.make_cmap([color_dict['green'], color_dict['blue'], color_dict['sand'], color_dict['pink'],color_dict['orange']])\n\n# To save them, use pickle\nimport pickle\n\npickle.dump(bit_cmap_dark, open('colourmaps/bit_cmap_dark.pkl', 'wb'))\npickle.dump(bit_cmap_light, open('colourmaps/bit_cmap_light.pkl', 'wb'))",
"execution_count": 43,
"outputs": []
},
{
"metadata": {},
"cell_type": "markdown",
"source": "***\n# 7 Let's try them with the dark theme\n## But first, activate the dark theme\n\n**NB: if you want to export with transparent background, for example when you have blue background slides, set `transparent = True` in `plt.savefig`."
},
{
"metadata": {
"code_folding": [],
"trusted": true
},
"cell_type": "code",
"source": "# Load the dark theme\nplt.style.use('bit_dark')",
"execution_count": 44,
"outputs": []
},
{
"metadata": {
"code_folding": [],
"scrolled": false,
"trusted": true
},
"cell_type": "code",
"source": "demo_1(\"Exports/dark_demo_1.png\") # <-- If you want vector quality, export as .svg\ndemo_2(\"Exports/dark_demo_2.png\")\ndemo_3(\"Exports/dark_demo_3.png\")\ndemo_4(\"Exports/dark_demo_4.png\")",
"execution_count": 1,
"outputs": []
},
{
"metadata": {},
"cell_type": "markdown",
"source": "***\n# 7 Extend the theme as you like\n\nThese are some basics and you will probably run into situations where this style sheet is not giving you what you want. You can easily extend it by adding rules to the `.mplstyle` files. For a global overview of all settings possible, check out [this Github](https://github.com/matplotlib/matplotlib/blob/master/matplotlibrc.template). Also handy for setting global parameters for all your plots in one file."
},
{
"metadata": {},
"cell_type": "markdown",
"source": "***\n# Happy plotting!"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "<!-- <img src=\"Assets/banner.png\"> -->\n<img src=\"https://www.dropbox.com/s/b3iasrh4al96r6z/banner.png?raw=1\">"
}
],
"metadata": {
"_draft": {
"nbviewer_url": "https://gist.github.com/908c8d2a398a914b04cbe00ad621191d"
},
"gist": {
"id": "908c8d2a398a914b04cbe00ad621191d",
"data": {
"description": "Bit data visualisation with Matplotlib",
"public": true
}
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3",
"language": "python"
},
"language_info": {
"name": "python",
"version": "3.6.10",
"mimetype": "text/x-python",
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"pygments_lexer": "ipython3",
"nbconvert_exporter": "python",
"file_extension": ".py"
},
"varInspector": {
"window_display": false,
"cols": {
"lenName": 16,
"lenType": 16,
"lenVar": 40
},
"kernels_config": {
"python": {
"library": "var_list.py",
"delete_cmd_prefix": "del ",
"delete_cmd_postfix": "",
"varRefreshCmd": "print(var_dic_list())"
},
"r": {
"library": "var_list.r",
"delete_cmd_prefix": "rm(",
"delete_cmd_postfix": ") ",
"varRefreshCmd": "cat(var_dic_list()) "
}
},
"types_to_exclude": [
"module",
"function",
"builtin_function_or_method",
"instance",
"_Feature"
]
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment