Pythonのwordcloudではmaskという引数を指定できます。このmaskに透過PNGを読み込ませて、表示領域を指定することができますので、ツイッターアイコンに似たWord Cloudも作成できます。
自分の好みの画像に合わせて色々作成することができますので視覚的にも楽しめます。
Word Cloudの使い方などはこちらの記事を参照ください。
cv2をインストール
maskの引数として画像を扱うために、画像処理するためのライブラリ群であるOpenCV(Open Souece Computer Vision Library)をインストールします。
例によってConoHa Wing環境のPythonにインストールしていますので–userを指定していますが、必須ではありません。
$ pip install --user opencv-python
cv2という名前でimportしますので、import時にエラーが発生しないことを確認しておきます。ちなみに、dir関数で引数オブジェクトが持つ変数や関数を確認することができます。関数名を確認したい時とかに意外に便利です。
$ python
Python 3.6.11 (default, Aug 11 2020, 06:48:17)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-39)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
>>> dir(cv2)
['', 'ACCESS_FAST', 'ACCESS_MASK', 'ACCESS_READ', 'ACCESS_RW', 'ACCESS_WRITE', 'ADAPTIVE_THRESH_GAUSSIAN_C', 'ADAPTIVE_THRESH_MEAN_C', 'AGAST_FEATURE_DETECTOR_AGAST_5_8', 'AGAST_FEATURE_DETECTOR_AGAST_7_12D',
:
透過PNG画像を用意する
maskとして使用するためには背景が透過となっているPNG画像ファイルを用意する必要があります。この透過部分には文字が表示されないことになります。cv2によって簡単に反転することもできますので、透過部分に文字を表示させることもできます。
例えばこのような透過PNG画像を用意しておきます。
画像に合わせてWord Cloudを表示する
準備ができたらcv2とwordcloudを組み合わせます。ここでは日本語も表示したいのでMeCabも使っています。
まずは全体のコードはこんな感じです。
import MeCab
import cv2
from wordcloud import WordCloud
TXT_PATH='./wagahaiwa_nekodearu_all.txt'
FONT_PATH='./rounded-mplus-1c-medium.ttf'
IMG_PATH='./twitterlogo.png'
OUTPUT_PATH='./wagahai.png'
def get_mask(img_path):
img = cv2.imread(img_path, -1)
a_img = img[:, :, 3]
result_img = cv2.bitwise_not(a_img)
return result_img
mecab = MeCab.Tagger('-Ochasen')
word_list = []
with open(TXT_PATH, 'r', encoding='utf-8') as f:
for line in f:
node = mecab.parseToNode(line)
while node:
word_type = node.feature.split(",")[0]
word = node.surface
if word != '' and word_type in ['形容詞','動詞','名詞','副詞']:
word_list.append(word)
node = node.next
wordcloud = WordCloud(font_path=FONT_PATH, width=500, height=300, background_color='white', max_font_size=80, mask=get_mask(IMG_PATH), min_font_size=2, max_words=500).generate(' '.join(word_list))
wordcloud.to_file(OUTPUT_PATH)
実行するとタイトル画像のようなWord Cloudの画像イメージが作成されます。ちなみに背景を逆転させるとこんな感じのWord Cloudになります。
以下では簡単なソースコードの説明をしていきます。
ファイルパス定義
TXT_PATH='./wagahaiwa_nekodearu_all.txt'
FONT_PATH='./rounded-mplus-1c-medium.ttf'
IMG_PATH='./twitterlogo.png'
OUTPUT_PATH='./wagahai.png'
それぞれのファイルパスを定義しています。このプログラムでは全てカレントディレクトリ上にあるファイルを相対パスで書いていますが、絶対パスで書いてもらっても大丈夫です。
- TXT_PATH:MeCabで分析する日本語文章が保存されているファイルのパス。
- FONT_PATH:日本語フォントファイルのパス。拡張子は.ttfか.otf。
- IMG_PATH:透過PNGファイルのパス。JPEGなどでは正しく処理できない。
- OUTPUT_PATH:Word Cloudを出力するファイルのパス。このプログラムでは画像ファイルとして出力。
透過PNGをmask画像に変換
def get_mask(img_path):
img = cv2.imread(img_path, -1)
a_img = img[:, :, 3]
result_img = cv2.bitwise_not(a_img)
return result_img
2行目のimread関数で引数に-1を指定することで、アルファチャンネル(透明度)も含めた画像として読み込みます。
3行目のimg[:, :, 3]については、画像処理の知識がないので詳細は割愛しますが、透過部分を黒色として、非透過部分を白色に変換します。黒色部分に単語が表示されますので、意図した結果になりません。
4行目で黒色部分と白色部分を反転し、意図した表示領域に変換して、5行目でその結果を返しています。
日本語文章の分析
mecab = MeCab.Tagger('-Ochasen')
word_list = []
with open(TXT_PATH, 'r', encoding='utf-8') as f:
for line in f:
node = mecab.parseToNode(line)
while node:
word_type = node.feature.split(",")[0]
word = node.surface
if word != '' and word_type in ['形容詞','動詞','名詞','副詞']:
word_list.append(word)
node = node.next
日本語文章ファイルを読み込んで、word_list配列に追加していきます。MeCabで分析すると品詞を区別できますので、ここでは形容詞、動詞、名詞、副詞のみを対象にしています。助詞を含めてしまうと意味がない単語が頻出語として現れてしまうため、そのような単語を避けています。
Word Cloud作成
wordcloud = WordCloud(font_path=FONT_PATH, width=500, height=300, background_color='white', max_font_size=80, mask=get_mask(IMG_PATH), min_font_size=2, max_words=500).generate(' '.join(word_list))
wordcloud.to_file(OUTPUT_PATH)
WordCloudを作成時にいくつかオプションを指定することで、出力する単語の数やフォントサイズを制御しています。mask画像が複雑な場合、あまり大きいフォントにしてしまうと、mask画像に入り切らずに歪な結果になってしまいます。
- mask=get_mask(IMG_PATH):mask画像を指定します。ここではget_mask関数で処理された結果をそのまま指定しています。
- min_font_size=2:デフォルトは4なので、より小さいフォントを出力したい場合に使用します。
- max_words=500:デフォルトは200です。出力する単語の数となり、あまり少ない数だと、画像に対してスカスカな結果になってしまうのである程度大きな値を指定しています。
その他のオプションについては、WordCloud for Python documentationを参照してください。
コメント
[…] 【Python】Word Cloudを使ってみるWord Cloudをご存じでしょうか。タイトルにある画像がWord Cloudで、こちらはオバマ大統領の演説内容をWord Cloud化してみた結果です。infomisc.blog2021.10.19 【Python】Word Cloudを使ってみる(応用編)Pythonのwordcloudではmaskという引数を指… […]