diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..42f35e0 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,8 @@ + +PR Checklist: +- [ ] comma-separated file of RGB values +- [ ] Jupyter notebook with the same name as the colormap. +- [ ] The notebook contains: + - [ ] an explanation of the colormap + - [ ] a color swatch + - [ ] an example of using the colormap \ No newline at end of file diff --git a/.gitignore b/.gitignore index c1c1639..a1a0bdf 100644 --- a/.gitignore +++ b/.gitignore @@ -20,7 +20,8 @@ __pycache__ pip-wheel-metadata **.ipynb_checkpoints __pycache__/ - +.vscode/* +*.code-workspace # nbsite # these files normally shouldn't be checked in as they should be # dynamically built from notebooks diff --git a/README.md b/README.md index 927942b..56ab85e 100644 --- a/README.md +++ b/README.md @@ -34,31 +34,26 @@ pip install contrib_colormaps ## Contributing -To add a colormap, open a pull request on this repository adding a -comma-separated file of RGB values to the contrib_colormaps/colormaps +To add a colormap, open a pull request on this repository adding the following files: + +1. comma-separated file of RGB values to the contrib_colormaps/colormaps directory. This file should look like: ``` -0,0.20755,0.97632 -0,0.22113,0.96201 +0, 0.20755, 0.97632 +0, 0.22113, 0.96201 ``` -This PR should also include a new notebook in -[examples/colormaps](examples/colormaps) with a name that matches the -name of the csv (e.g. for a new colormap called 'rainforest' with a csv -'rainforest.csv' there should be a corresponding 'rainforest.ipynb'). +2. A Jupyter notebook in [examples/colormaps](examples/colormaps) meeting the following criteria: -The last requirement is that you regenerate the baseline images used for tests. -First make sure you have holoviews, matplotlib, and pytest-mpl in your -environment. Then change directories into tests, and regenerate the plots - -``` -cd contrib_colorcets/tests -pytest --mpl-generate-path=baseline -``` + 1. a name that matches the name of the csv + e.g. for a new colormap called `rainforest` with a csv *rainforest.csv* there should be a corresponding *rainforest.ipynb* + 2. an explanation of the colormap - what is it? and when/why would someone use it? + 3. a swatch of the colormap - we recommend using our [swatch function](colormaps/index.ipynb), but it's not required + 3. at least one example plot using the colormap - it can be exclusively Bokeh, Matplotlib, or Holoviews +You can use this sample pull request as a model: [#3](https://github.com/pyviz/contrib_colormaps/pull/3) ## About PyViz - contrib_colormaps is part of the PyViz initiative for making Python-based visualization tools work well together. See [pyviz.org](http://pyviz.org). diff --git a/contrib_colormaps/plotting.py b/contrib_colormaps/plotting.py index 039b5d5..e839a04 100644 --- a/contrib_colormaps/plotting.py +++ b/contrib_colormaps/plotting.py @@ -12,7 +12,7 @@ array = np.meshgrid(np.linspace(0, 1, 256), np.linspace(0, 1, 10))[0] -def swatch(name, bounds=None, array=array, **kwargs): +def swatch(name, bounds=None, array=array, aspect=10, **kwargs): """Show swatch using matplotlib or bokeh via holoviews""" if bounds is None: bounds = (0, 0, 256, 1) @@ -20,16 +20,22 @@ def swatch(name, bounds=None, array=array, **kwargs): plot = hv.Image(array, bounds=bounds, group=name) backends = hv.Store.loaded_backends() if 'bokeh' in backends: - width = kwargs.pop('width', 900) - height = kwargs.pop('height', 100) - plot.opts(opts.Image(backend='bokeh', width=width, height=height, toolbar='above', - default_tools=['xwheel_zoom', 'xpan', 'save', 'reset'], + frame_height = kwargs.pop('frame_height', 60) + plot.opts(opts.Image(backend='bokeh', aspect=aspect, frame_height=frame_height, + toolbar='above', default_tools=['xwheel_zoom', 'xpan', 'save', 'reset'], cmap=palette[name])) if 'matplotlib' in backends: - aspect = kwargs.pop('aspect', 15) - fig_size = kwargs.pop('fig_size', 350) + def hook(plot, element): + plot.handles['axis'].axis('off') + plot.handles['axis'].set_title("sample", loc='left', + fontfamily='DejaVu Sans', fontsize=14, + fontweight='roman',fontstretch='semi-expanded') + + fig_size = kwargs.pop('fig_size', 300) + plot.opts(opts.Image(backend='matplotlib', aspect=aspect, fig_size=fig_size, - cmap=cm[name])) + title="", cmap=cm[name], hooks=[hook])) + return plot.opts(opts.Image(xaxis=None, yaxis=None), opts.Image(**kwargs)) diff --git a/doc/_static/custom.css b/doc/_static/custom.css new file mode 100644 index 0000000..d10e70e --- /dev/null +++ b/doc/_static/custom.css @@ -0,0 +1,11 @@ +div.body { + max-width: 80%; +} + +div.document { + margin: 30px auto 0 5%; +} + +div.footer { + width: 90%; +} diff --git a/doc/conf.py b/doc/conf.py index 8950b6d..8d882a7 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -10,11 +10,11 @@ version = release = contrib_colormaps.__version__ html_static_path += ['_static'] -html_favicon = 'favicon.ico' +html_favicon = '_static/favicon.ico' html_theme_options = { 'logo': 'logo.png', 'logo_name': True, - 'page_width': '90%', + 'page_width': '100%', 'font_family': "Ubuntu, sans-serif", 'font_size': '0.9em', 'link': '#347ab4', @@ -25,6 +25,19 @@ 'show_powered_by': False, } +extensions += ['nbsite.gallery'] + +nbsite_gallery_conf = { + 'github_org': 'pyviz', + 'github_project': 'contrib_colormaps', + 'galleries': { + 'colormaps': { + 'title': 'Colormaps', + 'intro': 'Gallery of colormaps included in contrib_colormaps' + } + }, +} + html_context.update({ 'PROJECT': project, 'DESCRIPTION': description, diff --git a/doc/index.rst b/doc/index.rst new file mode 100644 index 0000000..e51aa83 --- /dev/null +++ b/doc/index.rst @@ -0,0 +1,24 @@ +.. + Originally generated by nbsite (0.6.3): + /Users/jsignell/conda/envs/cc_dev/bin/nbsite generate-rst --org pyviz --project-name contrib_colormaps --offset 0 + Will not subsequently be overwritten by nbsite, so can be edited. + +***************** +Contrib Colormaps +***************** + +.. notebook:: contrib_colormaps ../examples/index.ipynb + :offset: 0 + +.. toctree:: + :titlesonly: + :maxdepth: 2 + :hidden: + + Introduction + Colormaps + + +------- + +`Right click to download this notebook from GitHub. `_ diff --git a/dodo.py b/dodo.py index 814d6a3..64da210 100644 --- a/dodo.py +++ b/dodo.py @@ -10,9 +10,9 @@ $ doit list -To run one command, for instance building the website, run: +To run one command, for instance building the docs, run: -$ doit build_website +$ doit build_docs """ from pyctdev import * # noqa: api diff --git a/examples/colormaps/index.ipynb b/examples/colormaps/index.ipynb deleted file mode 100644 index d44266e..0000000 --- a/examples/colormaps/index.ipynb +++ /dev/null @@ -1,136 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Accessing the colormaps\n", - "\n", - "After importing `contrib_colormaps` as `cc`, all the colormaps will be available for use in different forms. It's a bit difficult to describe, but the idea is that this library should have at least one such form convenient for any particular application. There are two different basic versions for each colormap, each of which is fundamentally a list of colors: \n", - "\n", - "1. A Bokeh-style palette, i.e., a Python list of RGB colors as hex strings, like ``['#000000', ..., '#ffffff']``\n", - "2. If matplotlib is installed and importable, a Matplotlib ``LinearSegmentedColormap`` using normalized magnitudes, like ``LinearSegmentedColormap.from_list(\"fire\",[ [0.0,0.0,0.0], ..., [1.0,1.0,1.0] ], 256)``\n", - "\n", - "The Bokeh-compatible palettes are provided as attributes in the ``contrib_colormaps`` namespace, with long names prefixed with ``b_``. E.g. ``rainforest`` can be accessed as ``cc.b_sample``. These names should tab complete once ``cc`` has been imported. Because Bokeh palettes are just Python lists, you can always reverse them using normal Python syntax, e.g. ``list(reversed(cc.b_sample))``, or use subsets of them with slice notation, e.g. ``cc.b_sample[25:]``. If you want to access the palettes by string name, they are also collected into a dictionary named ``palette``, so you can use ``cc.palette[\"sample\"]`` or ``cc.palette.sample``; whichever is more convenient.\n", - "\n", - "The Matplotlib colormaps are also provided as tab-completable attributes, but consistently with a prefix ``m_``, e.g. ``cc.m_sample``. Already reversed versions are also available, as ``cc.m_sample_r``. The same colormaps are also registered with matplotlib's string-based dictionary with the prefix ``cc_``, making them available by name within various matplotlib functions (e.g. ``cc_sample``, ``cc_sample_r``). Finally, if you want to access the colormaps by string name without using Matplotlib's registry, they are also stored in the ``cc.cm`` dictionary, e.g. ``cc.cm[\"sample\"]`` or ``cc.cm[\"sample_r\"]``." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Example\n", - "\n", - "Here we show importing sample and printing the first 5 colors. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "scrolled": true - }, - "outputs": [], - "source": [ - "import contrib_colormaps as cc\n", - "\n", - "cc.b_sample[:5]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Plotting\n", - "\n", - "For ease of use, we also provide minimal plotting commands for use with contrib_colormaps. These depend on holoviews, which needs to be installed before they can be used. Once set up, these commands provide easy viewing capability of the colormaps.\n", - "\n", - "#### Example\n", - "\n", - "Import `swatch` from `contrib_colormaps.plotting` and load your desired backend into holoviews. Then call `swatch` with the name of a colormap. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from contrib_colormaps.plotting import swatch\n", - "import holoviews as hv\n", - "hv.extension('bokeh', 'matplotlib', logo=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "scrolled": true - }, - "outputs": [], - "source": [ - "swatch('sample')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Usage\n", - "\n", - "All of the colormaps can be used directly in plotting libraries such as matplotlib or bokeh.\n", - "\n", - "#### Matplotlib" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "scrolled": true - }, - "outputs": [], - "source": [ - "import numpy as np\n", - "import contrib_colormaps as cc\n", - "import matplotlib.pyplot as plt\n", - "\n", - "xs, _ = np.meshgrid(np.linspace(0, 1, 80), np.linspace(0, 1, 10))\n", - "plt.imshow(xs, cmap=cc.cm.sample); # use tab completion to choose" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Bokeh" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import contrib_colormaps as cc\n", - "from bokeh.plotting import figure, show\n", - "\n", - "xs, _ = np.meshgrid(np.linspace(0, 1, 80), np.linspace(0, 1, 10))\n", - "p = figure(x_range=(0, 80), y_range=(0, 10), height=100, width=400)\n", - "\n", - "p.image(image=[xs], x=0, y=0, dw=80, dh=10, palette=cc.palette.sample) # use tab completion to choose\n", - "show(p)" - ] - } - ], - "metadata": { - "language_info": { - "name": "python", - "pygments_lexer": "ipython3" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/examples/index.ipynb b/examples/index.ipynb index 027072d..e105cbc 100644 --- a/examples/index.ipynb +++ b/examples/index.ipynb @@ -11,9 +11,16 @@ "[Bokeh](http://bokeh.pydata.org),\n", "[Matplotlib](http://matplotlib.org),\n", "[HoloViews](http://holoviews.org), and\n", - "[Datashader](https://github.com/pyviz/datashader). \n", + "[Datashader](https://github.com/pyviz/datashader). " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## View Colormap Swatches \n", "\n", - "Below are all the colormaps in the current version of the library. To contribute a new colormap, see the contributing section of the [README](https://github.com/pyviz/contrib_colormaps#contributing). To learn more about how to use the various colormaps and what each is for, see the [colormaps section](colormaps/index.ipynb)." + "For ease of use, we provide minimal plotting commands for use with contrib_colormaps. These depend on holoviews, which needs to be installed before they can be used. Once set up, these commands provide easy viewing capability of the colormaps." ] }, { @@ -22,11 +29,146 @@ "metadata": {}, "outputs": [], "source": [ - "from contrib_colormaps.plotting import swatches\n", - "import holoviews as hv\n", + "from contrib_colormaps.plotting import swatch\n", + "import holoviews as hv" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "hv.extension('matplotlib', logo=False)\n", + "swatch('sample')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ "hv.extension('bokeh', logo=False)\n", + "swatch('sample')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Accessing the colormaps\n", + "\n", + "After importing `contrib_colormaps` as `cc`, the colormaps will be available for use in different forms. This library should have at least one such form convenient for any particular application. This library generates two versions of each colormap:\n", + "\n", + "1. A Bokeh-style palette, i.e., a Python list of RGB colors as hex strings, like ``['#000000', ..., '#ffffff']``\n", + "2. A Matplotlib ``LinearSegmentedColormap``, i.e., a list of RGBA tuples, like ``[[0.0,0.0,0.0], ..., [1.0,1.0,1.0]])``" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Matplotlib" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import contrib_colormaps as cc\n", + "\n", + "import matplotlib.pyplot as plt\n", + "%matplotlib inline\n", + "\n", + "x = np.arange(-10,11)\n", + "fig, ax = plt.subplots(figsize=(5,2.5))\n", + "im = ax.scatter(x, -(x**2), c=(x**2), s=40, cmap=cc.cm.sample)\n", + "fig.colorbar(im)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Bokeh" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import contrib_colormaps as cc\n", + "\n", + "from bokeh.plotting import output_notebook, figure, show\n", + "from bokeh.transform import linear_cmap\n", + "from bokeh.models import ColorBar, LinearColorMapper\n", + "\n", + "output_notebook()\n", + "p = figure(plot_width=300,plot_height=150)\n", + "x = np.arange(-10, 11)\n", + "y = -(x**2)\n", + "source = {'x': x, 'y': y, 'c': y}\n", + "\n", + "color_mapper = LinearColorMapper(palette=cc.b_sample, low=-100, high=0)\n", + "color_bar = ColorBar(color_mapper=color_mapper, width=10, location=(0, 0))\n", + "\n", + "p.circle(source=source, x='x', y='y', color=linear_cmap('c', cc.b_sample, -100, 0), size=10)\n", + "p.add_layout(color_bar, 'right')\n", + "\n", + "show(p)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The Bokeh-compatible palettes are provided as attributes in the ``contrib_colormaps`` namespace, with long names prefixed with ``b_``. E.g. ``rainforest`` can be accessed as ``cc.b_sample``. These names should tab complete once ``cc`` has been imported. Because Bokeh palettes are just Python lists, you can always reverse them using normal Python syntax, e.g. ``list(reversed(cc.b_sample))``, or use subsets of them with slice notation, e.g. ``cc.b_sample[25:]``. If you want to access the palettes by string name, they are also collected into a dictionary named ``palette``, so you can use ``cc.palette[\"sample\"]`` or ``cc.palette.sample``; whichever is more convenient.\n", + "\n", + "The Matplotlib colormaps are also provided as tab-completable attributes, but consistently with a prefix ``m_``, e.g. ``cc.m_sample``. Already reversed versions are also available, as ``cc.m_sample_r``. The same colormaps are also registered with matplotlib's string-based dictionary with the prefix ``cc_``, making them available by name within various matplotlib functions (e.g. ``cc_sample``, ``cc_sample_r``). Finally, if you want to access the colormaps by string name without using Matplotlib's registry, they are also stored in the ``cc.cm`` dictionary, e.g. ``cc.cm[\"sample\"]`` or ``cc.cm[\"sample_r\"]``." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here we show importing sample and printing the first 5 colors. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "cc.b_sample[:5]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "[cc.m_sample(i) for i in range(5)]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Contributing\n", "\n", - "swatches()" + "To contribute a new colormap, see the contributing section of the [README](https://github.com/pyviz/contrib_colormaps#contributing). To learn more about how to use the various colormaps and what each is for, see the [colormaps section](colormaps)." ] } ], @@ -37,5 +179,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/setup.py b/setup.py index 8581855..5d6b9ed 100644 --- a/setup.py +++ b/setup.py @@ -24,6 +24,7 @@ 'doc': examples + [ 'nbsite >=0.6.1', 'tornado<6', + 'selenium', ], 'tests_extra': tests + [ 'pytest-mpl' # only available on pip and conda-forge