{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Colored by Group Example\n\nGenerating a word cloud that assigns colors to words based on\na predefined mapping from colors to words\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "from wordcloud import (WordCloud, get_single_color_func)\nimport matplotlib.pyplot as plt\n\n\nclass SimpleGroupedColorFunc(object):\n    \"\"\"Create a color function object which assigns EXACT colors\n       to certain words based on the color to words mapping\n\n       Parameters\n       ----------\n       color_to_words : dict(str -> list(str))\n         A dictionary that maps a color to the list of words.\n\n       default_color : str\n         Color that will be assigned to a word that's not a member\n         of any value from color_to_words.\n    \"\"\"\n\n    def __init__(self, color_to_words, default_color):\n        self.word_to_color = {word: color\n                              for (color, words) in color_to_words.items()\n                              for word in words}\n\n        self.default_color = default_color\n\n    def __call__(self, word, **kwargs):\n        return self.word_to_color.get(word, self.default_color)\n\n\nclass GroupedColorFunc(object):\n    \"\"\"Create a color function object which assigns DIFFERENT SHADES of\n       specified colors to certain words based on the color to words mapping.\n\n       Uses wordcloud.get_single_color_func\n\n       Parameters\n       ----------\n       color_to_words : dict(str -> list(str))\n         A dictionary that maps a color to the list of words.\n\n       default_color : str\n         Color that will be assigned to a word that's not a member\n         of any value from color_to_words.\n    \"\"\"\n\n    def __init__(self, color_to_words, default_color):\n        self.color_func_to_words = [\n            (get_single_color_func(color), set(words))\n            for (color, words) in color_to_words.items()]\n\n        self.default_color_func = get_single_color_func(default_color)\n\n    def get_color_func(self, word):\n        \"\"\"Returns a single_color_func associated with the word\"\"\"\n        try:\n            color_func = next(\n                color_func for (color_func, words) in self.color_func_to_words\n                if word in words)\n        except StopIteration:\n            color_func = self.default_color_func\n\n        return color_func\n\n    def __call__(self, word, **kwargs):\n        return self.get_color_func(word)(word, **kwargs)\n\n\ntext = \"\"\"The Zen of Python, by Tim Peters\nBeautiful is better than ugly.\nExplicit is better than implicit.\nSimple is better than complex.\nComplex is better than complicated.\nFlat is better than nested.\nSparse is better than dense.\nReadability counts.\nSpecial cases aren't special enough to break the rules.\nAlthough practicality beats purity.\nErrors should never pass silently.\nUnless explicitly silenced.\nIn the face of ambiguity, refuse the temptation to guess.\nThere should be one-- and preferably only one --obvious way to do it.\nAlthough that way may not be obvious at first unless you're Dutch.\nNow is better than never.\nAlthough never is often better than *right* now.\nIf the implementation is hard to explain, it's a bad idea.\nIf the implementation is easy to explain, it may be a good idea.\nNamespaces are one honking great idea -- let's do more of those!\"\"\"\n\n# Since the text is small collocations are turned off and text is lower-cased\nwc = WordCloud(collocations=False).generate(text.lower())\n\ncolor_to_words = {\n    # words below will be colored with a green single color function\n    '#00ff00': ['beautiful', 'explicit', 'simple', 'sparse',\n                'readability', 'rules', 'practicality',\n                'explicitly', 'one', 'now', 'easy', 'obvious', 'better'],\n    # will be colored with a red single color function\n    'red': ['ugly', 'implicit', 'complex', 'complicated', 'nested',\n            'dense', 'special', 'errors', 'silently', 'ambiguity',\n            'guess', 'hard']\n}\n\n# Words that are not in any of the color_to_words values\n# will be colored with a grey single color function\ndefault_color = 'grey'\n\n# Create a color function with single tone\n# grouped_color_func = SimpleGroupedColorFunc(color_to_words, default_color)\n\n# Create a color function with multiple tones\ngrouped_color_func = GroupedColorFunc(color_to_words, default_color)\n\n# Apply our color function\nwc.recolor(color_func=grouped_color_func)\n\n# Plot\nplt.figure()\nplt.imshow(wc, interpolation=\"bilinear\")\nplt.axis(\"off\")\nplt.show()"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "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.13.5"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}