Skip to content

Commit

Permalink
Merge pull request #10 from minimaxir/0.3
Browse files Browse the repository at this point in the history
0.3
  • Loading branch information
minimaxir authored Nov 10, 2019
2 parents ebeef0a + 688e115 commit 81d9f6f
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 31 deletions.
45 changes: 34 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ stylecloud is a Python package that leverages the popular [word_cloud](https://g

* Icon shapes (of any size!) for wordclouds (via [Font Awesome](https://fontawesome.com) 5.11.2)
* Support for advanced color palettes (via [palettable](https://jiffyclub.github.io/palettable/))
* Manual color selection for text and backgrounds,
* Directional gradients w/ the aforementioned palettes.
* Supports reading a file of text, or reading a pre-generated CSV with words and counts.
* Supports reading text files and CSVs (either one-column w/ texts, or two columns w/ words+weights).
* Command Line Interface!

This package is a more formal implementation of my [stylistic word cloud project](https://minimaxir.com/2016/05/wordclouds/) from 2016.
Expand All @@ -24,7 +25,7 @@ pip3 install stylecloud

## Usage

You can use stylecloud in a Python script or as a standalone CLI app. For example, let's say you have a text of the U.S. Constitution `constitution.txt`.
You can use stylecloud in a Python script or as a standalone CLI app. For example, let's say you have a [text](https://github.com/amueller/word_cloud/blob/master/examples/constitution.txt) of the U.S. Constitution `constitution.txt`.

Python script:

Expand Down Expand Up @@ -64,21 +65,41 @@ stylecloud --file_path constitution.txt --icon_name 'fas fa-dog' --palette color

You can find more examples of styleclouds, including how to make styleclouds from Twitter and Reddit data, in the [stylecloud-examples](https://github.com/minimaxir/stylecloud-examples) repo.

In order to deal with different languages or simply add list of custom stopwords it is possible to pass a list contained in a string as parameter like so :
### Custom Colors for stylecloud Text

You can manually specify the color(s) of the text with the `colors` parameter, overriding the palettes. This can be useful for specific branding, or high-contrast visualizations. However, manual color selection not work with gradients.

```python
import stylecloud

stylecloud.gen_stylecloud(file_path='constitution.txt',
colors=['#ecf0f1', '#3498db', '#e74c3c'],
background_color='#1A1A1A')
```

```sh
stylecloud --file_path constitution.txt --custom_words "[thereof, may, state, united states]"
stylecloud --file_path constitution.txt --colors "['#ecf0f1', '#3498db', '#e74c3c']" --background_color '#1A1A1A'
```

For more control it would of course be most ideal to define the list in code since if one is defining stopwords for another language these lists can get long. In that case simply pass in the list as argument to the function
![](https://github.com/minimaxir/stylecloud-examples/raw/master/hello-world/stylecloud5.png)

### Stopwords

In order to filter out stopwords in non-English languages or use custom stopwords, you can pass a list of words to the `custom_stopwords` parameter:

```python
import stylecloud
my_long_list = ["thereof", "may", "state", "united states"]

stylecloud.gen_stylecloud(file_path=constitution.txt, custom_words=my_long_list)
stylecloud.gen_stylecloud(file_path=constitution.txt,
custom_stopwords=my_long_list)
```

```sh
stylecloud --file_path constitution.txt --custom_stopwords "[thereof, may, state, united states]"
```
Good resources for stopwords in other languages are the [stop-words python package](https://github.com/Alir3z4/python-stop-words) which gives you python lists directly. Or as JSON arrays this list of [iso stopword collections](https://github.com/stopwords-iso/stopwords-iso).

Good resources for stopwords in other languages are the [stop-words Python package](https://github.com/Alir3z4/python-stop-words) and the [ISO stopword collections](https://github.com/stopwords-iso/stopwords-iso).

### Helpful Parameters

Expand All @@ -89,15 +110,17 @@ These parameters are valid for both the Python function and the CLI (you can use
* gradient: Direction of gradient. (if not None, the stylecloud will use a directional gradient) [default: `None`]
* size: Size (length and width in pixels) of the stylecloud. [default: `512`]
* icon_name: Icon Name for the stylecloud shape. (e.g. 'fas fa-grin') [default: `fas fa-flag`]
* palette: Color palette (via palettable) [default: `cartocolors.qualitative.Bold_6`]
* palette: Color palette (via palettable) [default: `cartocolors.qualitative.Bold_5`]
* colors: Color(s) to use as the text colors. Overrides both gradient and palette if specified [default: `None`]
* background_color: Background color (name or hex) [default: `white`]
* max_font_size: Maximum font size in the stylecloud. [default: `200`]
* max_words: Maximum number of words to include in the stylecloud. [default: `2000`]
* stopwords: Boolean to filter out common stopwords. [default: `True`]
* custom_stopwords: list of custom stopwords. e.g: For other languages than english [default: `STOPWORDS`]
* custom_stopwords: list of custom stopwords. e.g: For other languages than english [default: `STOPWORDS`, via `word_cloud`]
* output_name: Output file name of the stylecloud. [default: `stylecloud.png`]
* font_path: Path to .ttf file for font to use in stylecloud. [default: uses included Staatliches font]
* random_state: Controls random state of words and colors.
* random_state: Controls random state of words and colors. [default: `None`]
* collocations: Whether to include collocations (bigrams) of two words. Same behavior as base `word_cloud` package. [default: `True`]

## Helpful Notes

Expand All @@ -119,7 +142,7 @@ These parameters are valid for both the Python function and the CLI (you can use

Max Woolf ([@minimaxir](https://minimaxir.com))

*Max's open-source projects are supported by his [Patreon](https://www.patreon.com/minimaxir) and GitHub Sponsors. If you found this project helpful, any monetary contributions to the Patreon are appreciated and will be put to good creative use.*
*Max's open-source projects are supported by his [Patreon](https://www.patreon.com/minimaxir) and [GitHub Sponsors](https://github.com/sponsors/minimaxir). If you found this project helpful, any monetary contributions to the Patreon are appreciated and will be put to good creative use.*

## License

Expand Down
9 changes: 5 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
long_description = '''
Generate stylistic wordclouds, including gradients and icon shapes!
stylecloud is a Python package leverages the popular [word_cloud](https://github.com/amueller/word_cloud) package, adding useful features to create truly unique word clouds!
stylecloud is a Python package that leverages the popular [word_cloud](https://github.com/amueller/word_cloud) package, adding useful features to create truly unique word clouds!
* Icon shapes for wordclouds (via [Font Awesome](https://fontawesome.com) 5.11.2)
* Icon shapes (of any size!) for wordclouds (via [Font Awesome](https://fontawesome.com) 5.11.2)
* Support for advanced color palettes (via [palettable](https://jiffyclub.github.io/palettable/))
* Manual color selection for text and backgrounds,
* Directional gradients w/ the aforementioned palettes.
* Supports reading a file of text, or reading a pre-generated CSV with words and counts.
* Supports reading text files and CSVs (either one-column w/ texts, or two columns w/ words+weights).
* Command Line Interface!
This package is a more formal implementation of my [stylistic word cloud project](https://minimaxir.com/2016/05/wordclouds/) from 2016.
Expand All @@ -18,7 +19,7 @@
setup(
name='stylecloud',
packages=['stylecloud'], # this must be the same as the name above
version='0.2',
version='0.3',
description="Python package + CLI to generate stylistic wordclouds, " \
"including gradients and icon shapes!",
long_description=long_description,
Expand Down
57 changes: 41 additions & 16 deletions stylecloud/stylecloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import csv
import os
from PIL import Image
from matplotlib.colors import makeMappingArray
from matplotlib.colors import makeMappingArray, to_rgb
import numpy as np
import fire
from shutil import rmtree
Expand Down Expand Up @@ -111,11 +111,23 @@ def gen_gradient_mask(size, palette, icon_dir='.temp',
return image_colors, np.uint8(mask_array)


def color_to_rgb(color):
"""Converts a color to a RGB tuple from (0-255)."""
if isinstance(color, tuple):
# if a RGB tuple already
return color
else:
# to_rgb() returns colors from (0-1)
color = tuple(int(x * 255) for x in to_rgb(color))
return color


def gen_stylecloud(text=None,
file_path=None,
size=512,
icon_name='fas fa-flag',
palette='cartocolors.qualitative.Bold_6',
palette='cartocolors.qualitative.Bold_5',
colors=None,
background_color="white",
max_font_size=200,
max_words=2000,
Expand All @@ -134,7 +146,8 @@ def gen_stylecloud(text=None,
:param size: Size (length and width in pixels) of the stylecloud.
:param icon_name: Icon Name for the stylecloud shape. (e.g. 'fas fa-grin')
:param palette: Color palette (via palettable)
:param background_color: Background color (name or hex)
:param colors: Custom color(s) for text (name or hex). Overrides palette.
:param background_color: Background color (name or hex).
:param max_font_size: Maximum font size in the stylecloud.
:param max_words: Maximum number of words to include in the stylecloud.
:param stopwords: Boolean to filter out common stopwords.
Expand All @@ -155,20 +168,30 @@ def gen_stylecloud(text=None,

gen_fa_mask(icon_name, size, icon_dir)

if gradient:
colors, mask_array = gen_gradient_mask(size, palette, icon_dir,
gradient)
if gradient and colors is None:
pal_colors, mask_array = gen_gradient_mask(size, palette, icon_dir,
gradient)
else: # Color each word randomly from the palette
mask_array = gen_mask_array(icon_dir, 'uint8')
palette_func = gen_palette(palette)

# See also:
# https://amueller.github.io/word_cloud/auto_examples/a_new_hope.html
def colors(word, font_size, position,
orientation, random_state,
**kwargs):
rand_color = np.random.randint(0, palette_func.number - 1)
return tuple(palette_func.colors[rand_color])
if colors:
# if specifying a single color string
if isinstance(colors, str):
colors = [colors]

# iterate through each color to ensure correct RGB format.
# see matplotlib docs on how colors are decoded:
# https://matplotlib.org/3.1.1/api/colors_api.html
colors = [color_to_rgb(color) for color in colors]

else:
palette_func = gen_palette(palette)
colors = palette_func.colors

def pal_colors(word, font_size, position,
orientation, random_state,
**kwargs):
rand_color = np.random.randint(0, len(colors))
return tuple(colors[rand_color])

# cleanup icon folder
rmtree(icon_dir)
Expand All @@ -184,8 +207,10 @@ def colors(word, font_size, position,
if isinstance(text, str):
wc.generate_from_text(text)
else: # i.e. a dict of word:value from a CSV
if stopwords: # manually remove stopwords since otherwise ignored
text = {k: v for k, v in text.items() if k not in custom_stopwords}
wc.generate_from_frequencies(text)
wc.recolor(color_func=colors, random_state=random_state)
wc.recolor(color_func=pal_colors, random_state=random_state)
wc.to_file(output_name)


Expand Down

0 comments on commit 81d9f6f

Please sign in to comment.