はじめに
Pythonでデータ可視化やグラフ作成を行う際に欠かせないライブラリであるMatplotlibですが、macOSで使用していると以下のようなエンコーディングエラーに遭遇することがあります。
Cannot decode configuration file ... as utf-8.
'utf-8' codec can't decode byte 0xb0 in position 37: invalid start byte
この記事では、この問題の原因と解決方法について説明します。実際にワードクラウド生成ツールの開発中に出くわした事例をもとに、具体的な対処法を紹介します。
問題の発生状況
エラーメッセージ
典型的なエラーメッセージは以下のようなものです:
Cannot decode configuration file PosixPath('/path/to/matplotlib/mpl-data/stylelib/.__classic_test_patch.mplstyle') as utf-8.
'utf-8' codec can't decode byte 0xb0 in position 37: invalid start byte
このエラーは、wordcloud
のような、内部的にMatplotlibに依存するライブラリを使用しているときにも発生します。
実際のエラー出力例
実際のテスト実行時には、以下のようなエラーが表示されます:
シンプルなワードクラウドのテスト開始...
テキスト長: 291 文字
テキストを処理中...
単語数: 28
テスト: 8
ワードクラウド: 6
画像: 6
生成: 5
Python: 3
単語: 3
テキスト: 2
サンプル: 1
使っ: 1
日本語: 1
ワードクラウド生成中...
Cannot decode configuration file PosixPath('/path/to/matplotlib/mpl-data/stylelib/._seaborn-v0_8-notebook.mplstyle') as utf-8.
ワードクラウド画像生成中にエラーが発生しました: 'utf-8' codec can't decode byte 0xb0 in position 37: invalid start byte
どんなコードで発生するか
以下のような単純なワードクラウド生成コードでも問題が発生することがあります:
from wordcloud import WordCloud
import matplotlib.pyplot as plt
# テキストデータ
text = "Python データ分析 可視化 matplotlib エラー 解決 macOS エンコーディング 問題 対策"
# ワードクラウドを生成
wordcloud = WordCloud(width=800, height=400, background_color='white').generate(text)
# 表示
plt.figure(figsize=(10, 5))
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis('off')
plt.show()
原因
この問題は主に以下の原因で発生します:
-
macOSのリソースフォーク: macOSはファイルにメタデータを格納するために「リソースフォーク」と呼ばれる仕組みを使用しており、これが「._」や「.__」で始まる隠しファイルとして現れます
-
非UTF-8エンコーディング: これらの隠しファイルは通常UTF-8以外のエンコーディング(MacRomanなど)を使用していますが、Matplotlibはファイルの読み込み時にUTF-8を想定しています
-
stylelib内の隠しファイル: Matplotlibはスタイル設定を
mpl-data/stylelib
ディレクトリから読み込みますが、このディレクトリに存在する「._」で始まるファイルがエラーの原因となります
解決方法
方法1: 問題のスタイルファイルを修正する
問題を解決する最も直接的な方法は、エラーの原因となっている隠しファイルを修正または削除することです。
find . -name "._*" -delete
このコマンドを実行すると、問題のあるファイルを検出して修正します。
方法2: matplotlibを再インストールする
特定のバージョンのMatplotlibを指定して再インストールすることでも問題が解決する場合があります:
pip install --force-reinstall matplotlib==3.5.3
方法3: システムレベルの対応
macOSの設定で「._」ファイルの作成を抑制することもできます:
# ._ ファイルの作成を抑制
defaults write com.apple.desktopservices DSDontWriteNetworkStores true
実践例: ワードクラウド生成での対応
実際のプロジェクトでは、matplotlibに依存しない方法でワードクラウドを生成することで問題を回避することも可能です:
from wordcloud import WordCloud
from janome.tokenizer import Tokenizer
def create_wordcloud_without_matplotlib(text, output_path, width=1920, height=1080):
"""matplotlibに依存せずにワードクラウドを生成する"""
# テキストを処理
t = Tokenizer()
tokens = t.tokenize(text)
# 単語の頻度をカウント
word_frequencies = {}
valid_pos = ['名詞', '動詞', '形容詞']
for token in tokens:
pos = token.part_of_speech.split(',')[0]
if pos in valid_pos and len(token.surface) > 1:
word = token.surface
word_frequencies[word] = word_frequencies.get(word, 0) + 1
# ワードクラウドを生成
wc = WordCloud(
width=width,
height=height,
background_color="white",
prefer_horizontal=0.9,
regexp=r"[\w\p{Han}\p{Hiragana}\p{Katakana}]+",
max_words=200
)
# 頻度から生成
wc.generate_from_frequencies(word_frequencies)
# 画像を直接ファイルに保存(matplotlibを使わない)
wc.to_file(output_path)
return True
このコードはmatplotlibのplt.figure()
やplt.imshow()
を使用せず、WordCloud.to_file()
メソッドを直接呼び出すことでワードクラウド画像を生成します。
修正後の実行結果例
シンプルなワードクラウドのテスト開始...
テキスト長: 291 文字
テキストを処理中...
単語数: 28
テスト: 8
ワードクラウド: 6
画像: 6
生成: 5
Python: 3
単語: 3
テキスト: 2
サンプル: 1
使っ: 1
日本語: 1
ワードクラウド生成中...
ワードクラウド画像が 20250322_simple_wordcloud.png に保存されました。
ファイルサイズ: 19529 バイト
生成されるワードクラウドの例
修正が成功すると、以下のようなワードクラウド画像が生成されます。
まとめ
Mac OSだと ._ で始まる隠しファイルによってしばしば問題が発生します。適宜ファイル削除すれば問題解決可能ですが、ちょっと気が付きづらい。。。