amueller / word_cloud

A little word cloud generator in Python
https://amueller.github.io/word_cloud
MIT License
10.02k stars 2.31k forks source link

OSError: invalid pixel size when using NotoColorEmoji.ttf #603

Open colinschwegmann opened 3 years ago

colinschwegmann commented 3 years ago

Description

I can't use the NotoColorEmoji font as the font_path in a WC instance. It errors with OSError: invalid pixel size.

It is likely an issue with PIL: https://github.com/python-pillow/Pillow/issues/3346

I've tried to fix it locally by changing the ImageFont.truetype call in word_cloud but that didn't help.

Steps/Code to Reproduce

Just swapped out the ttf font from the emoji example.

Example (https://amueller.github.io/word_cloud/auto_examples/emoji.html):

import io
import os
import string
from os import path
from wordcloud import WordCloud

# get data directory (using getcwd() is needed to support running example in generated IPython notebook)
d = path.dirname(__file__) if "__file__" in locals() else os.getcwd()

# It is important to use io.open to correctly load the file as UTF-8
text = io.open(path.join(d, 'all.txt')).read()

# the regex used to detect words is a combination of normal words, ascii art, and emojis
# 2+ consecutive letters (also include apostrophes), e.x It's
normal_word = r"(?:\w[\w']+)"
# 2+ consecutive punctuations, e.x. :)
ascii_art = r"(?:[{punctuation}][{punctuation}]+)".format(punctuation=string.punctuation)
# a single character that is not alpha_numeric or other ascii printable
emoji = r"(?:[^\s])(?<![\w{ascii_printable}])".format(ascii_printable=string.printable)
regexp = r"{normal_word}|{ascii_art}|{emoji}".format(normal_word=normal_word, ascii_art=ascii_art,
                                                     emoji=emoji)

# Generate a word cloud image
font_path = path.join(d, 'NotoColorEmoji.ttf')
wc = WordCloud(font_path=font_path, regexp=regexp).generate(text)

# store to file
wc.to_file(path.join(d, "emoji.png"))

# Display the generated image:
# the matplotlib way:
import matplotlib.pyplot as plt
plt.imshow(wc)
plt.axis("off")
plt.show()

Expected Results

A word cloud with emoji's (and words).

Actual Results

The error OSError: invalid pixel size. Specifically:

Traceback (most recent call last):
  File "emoji.py", line 36, in <module>
    wc = WordCloud(font_path=font_path, regexp=regexp).generate(text)
  File "/home/user_name/git/personal/whatsapp/other/.pyenv/lib/python3.7/site-packages/wordcloud/wordcloud.py", line 631, in generate
    return self.generate_from_text(text)
  File "/home/user_name/git/personal/whatsapp/other/.pyenv/lib/python3.7/site-packages/wordcloud/wordcloud.py", line 613, in generate_from_text
    self.generate_from_frequencies(words)
  File "/home/user_name/git/personal/whatsapp/other/.pyenv/lib/python3.7/site-packages/wordcloud/wordcloud.py", line 447, in generate_from_frequencies
    max_font_size=self.height)
  File "/home/user_name/git/personal/whatsapp/other/.pyenv/lib/python3.7/site-packages/wordcloud/wordcloud.py", line 496, in generate_from_frequencies
    font = ImageFont.truetype(self.font_path, font_size)
  File "/home/user_name/git/personal/whatsapp/other/.pyenv/lib/python3.7/site-packages/PIL/ImageFont.py", line 689, in truetype
    return freetype(os.path.join(walkroot, walkfilename))
  File "/home/user_name/git/personal/whatsapp/other/.pyenv/lib/python3.7/site-packages/PIL/ImageFont.py", line 652, in freetype
    return FreeTypeFont(font, size, index, encoding, layout_engine)
  File "/home/user_name/git/personal/whatsapp/other/.pyenv/lib/python3.7/site-packages/PIL/ImageFont.py", line 194, in __init__
    font, size, index, encoding, layout_engine=layout_engine
OSError: invalid pixel size

Versions

Linux-5.0.0-38-generic-x86_64-with-Ubuntu-19.04-disco
Python 3.7.3 (default, Oct  7 2019, 12:56:13) 
[GCC 8.3.0]
NumPy 1.19.2
matplotlib 3.3.2
wordcoud 1.8.0
amueller commented 3 years ago

Thanks for reporting, but yes, it looks like a limitation of PIL handling the particular font. You could try the svg export and see if that works.

Maigre commented 1 year ago

Hi, facing the same issue, but i don't get the "try the svg export and see if that works." Any help on using Noto-emoji with PIL without firing OSError: invalid pixel size ? Thanks !

amueller commented 1 year ago

I was refering to using the to_svg method in the Wordcloud object. Hope that helps! Otherwise, as mentioned above, this is a PIL issue.