Matplotlib のフォント#

Matplotlib は、テキスト エンジンで動作するフォントを必要とし、その一部はインストールと共に出荷されます。デフォルトのフォントはDejaVu Sansで、ヨーロッパのほとんどの書記体系に対応しています。ただし、ユーザーは既定のフォントを構成し、独自のカスタム フォントを提供できます。詳細については、テキスト プロパティのカスタマイズを参照してください。特に、DejaVu Sans でサポートされていないグリフについては、ラテン文字以外のグリフを含むテキストを参照してください。

Matplotlib には、テキスト レンダリングを TeX エンジンにオフロードするオプションも用意されています ( usetex=True) 。 LaTeX を使用したテキスト レンダリング を参照してください。

PDF および PostScript のフォント#

フォントにはコンピューティングにおける長い (そして時には互換性のない) 歴史があり、さまざまな種類のフォントをサポートするさまざまなプラットフォームにつながっています。実際には、Matplotlib がサポートする 3 種類のフォント仕様があります (ガイドの後半で説明する pdf の「コア フォント」に加えて)。

フォントの種類#

タイプ1(PDF)

タイプ 3 (PDF/PS)

TrueType (PDF)

Adobe によって導入された最も古いタイプの 1 つ

導入の点ではタイプ 1 に似ています

Apple によって導入された、現在一般的に使用されている以前のタイプよりも新しいタイプ

PostScript の制限付きサブセット、文字列はバイトコード

完全な PostScript 言語により、任意のコードを埋め込むことができます (理論的には、ラスタライズ時にフラクタルをレンダリングすることさえできます!)

コードを実行できる仮想マシンを含めてください!

これらのフォントはフォントヒントをサポートしています

フォントヒントをサポートしない

ヒントのサポート (仮想マシンが「ヒント」を処理します)

Matplotlib による非サブセット化

外部モジュールttconv によるサブセット化

外部モジュールfonttools によるサブセット化

注: アドビは、2023 年 1 月に Type 1 フォントを使用したオーサリングのサポートを無効にします。詳細については、こちらを参照してください。

Matplotlib がサポートするその他のフォント仕様:

  • Type 42 フォント (PS):

  • OpenType フォント:

    • OpenType は、Adobe と Microsoft が共同で開発したデジタル タイプ フォントの新しい標準です。

    • 通常、はるかに大きな文字セットが含まれています。

    • Matplotlib の限定サポート

フォントのサブセット化#

PDF および PostScript 形式は、ファイルへのフォントの埋め込みをサポートしているため、表示プログラムは、ビューアのコンピューターにインストールされているフォントに関係なく、テキストを事前にラスタライズする必要なく、テキストを正しくレンダリングできます。これにより、出力がズームまたはサイズ変更された場合に、テキストがピクセル化されなくなります。ただし、フル フォントをファイルに埋め込むと、出力ファイルが大きくなる可能性があります。特に、CJK (中国語/日本語/韓国語) をサポートするフォントなど、多くのグリフを含むフォントの場合に顕著です。

この問題の解決策は、ドキュメントで使用されているフォントをサブセット化し、実際に使用されているグリフのみを埋め込むことです。これにより、ベクター テキストと小さなファイル サイズの両方が取得されます。必要なフォントのサブセットを計算することと、新しい (削減された) フォントを作成することはどちらも複雑な問題であるため、Matplotlib は fontToolsとttconvのベンダー フォークに依存しています。

現在、Type 3、Type 42、および TrueType フォントはサブセット化されています。Type 1 フォントはそうではありません。

コア フォント#

フォントを埋め込む機能に加えて、PostScriptおよびPDF 仕様の一部として、 準拠するビューアーが利用可能であることを確認する必要がある 14 のコア フォントがあります。ドキュメントをこれらのフォントのみに制限する場合、ドキュメントにフォント情報を埋め込む必要はありませんが、ベクター テキストを取得できます。

これは、本当に軽量なドキュメントを生成するのに特に役立ちます:

# trigger core fonts for PDF backend
plt.rcParams["pdf.use14corefonts"] = True
# trigger core fonts for PS backend
plt.rcParams["ps.useafm"] = True

chars = "AFM ftw!"
fig, ax = plt.subplots()
ax.text(0.5, 0.5, chars)

fig.savefig("AFM_PDF.pdf", format="pdf")
fig.savefig("AFM_PS.ps", format="ps)

SVG のフォント#

rcParams["svg.fonttype"]テキストは(デフォルト: 'path')によって制御される 2 つの方法で SVG に出力できます。

  • 'path'SVGのパス ( ) として

  • 要素にフォント スタイルを設定した SVG の文字列として ( 'none')

Matplotlib経由で保存'path'すると、ベクター パスとして使用されるグリフのパスが計算され、それらが出力に書き込まれます。これの利点は、インストールされているフォントに関係なく、すべてのコンピューターで SVG が同じように見えることです。ただし、テキストは事後に編集できなくなります。対照的に、 で保存する'none'とファイルが小さくなり、テキストがマークアップに直接表示されます。ただし、外観は、SVG ビューアと使用可能なフォントによって異なる場合があります。

Agg のフォント数 #

テキストを Agg 経由でラスター形式に出力するために、Matplotlib はFreeTypeに依存しています。グリフの正確なレンダリングは FreeType バージョン間で異なるため、画像比較テスト用に特定のバージョンに固定します。

Matplotlib がフォントを選択する方法#

Matplotlib で Font を内部的に使用するには、次の 3 つの手順を実行します。

  1. オブジェクトが作成されたFontProperties(明示的または暗黙的に)

  2. FontPropertiesメソッドがオブジェクトに基づいて、FontManagerMatplotlib が認識している最も近い「最適な」フォントを選択するために使用されます ( 'none'SVG のモードを除く)。

  3. フォント オブジェクトの Python プロキシは、テキストをレンダリングするためにバックエンド コードによって使用されます。正確な詳細は、font_manager.get_font.

「最適な」フォントを選択するアルゴリズムは、Web ブラウザーで使用されるCSS1 仕様で指定されたアルゴリズムの修正版です。このアルゴリズムでは、フォント ファミリ名 ("Arial"、"Noto Sans CJK"、"Hack" など)、サイズ、スタイル、ウェイトが考慮されます。フォントに直接マップされるファミリー名に加えて、5 つの「汎用フォント ファミリー名」(セリフ、モノスペース、ファンタジー、筆記体、およびサンセリフ) があり、これらは一連のフォントのいずれかに内部的にマップされます。

現在、ステップ 2 を実行するための公開 API はFontManager.findfont(そして、グローバルFontManagerインスタンスのそのメソッドは、モジュール レベルで としてエイリアス 化されていますfont_manager.findfont)、単一のフォントのみを検索し、ファイル システム上のフォントへの絶対パスを返します。

フォント フォールバック#

Unicode 空間全体をカバーするフォントは存在しないため、単一のフォントでは満たすことができないグリフの組み合わせをユーザーが要求する可能性があります。Figure 内で複数のフォントを個別の Textインスタンスで使用することは可能でしたが、以前はText(Web ブラウザーのように) 同じインスタンスで複数のフォントを使用することはできませんでした。TextMatplotlib 3.6 の時点で、Agg、SVG、PDF、および PS バックエンドは、単一のインスタンスで複数のフォントを「フォールバック」し ます。

fig, ax = plt.subplots()
ax.text(
    .5, .5, "There are 几个汉字 in between!",
    family=['DejaVu Sans', 'WenQuanYi Zen Hei'],
    ha='center'
)

(ソースコードpng )

../../_images/fonts-1.png

文字列「その間に几个汉字があります!」2 フォントでレンダリングされます。#

内部的には、これはオブジェクトの「フォント ファミリー」を FontPropertiesフォント ファミリーのリストに設定することによって実装されます。ft2font.FT2Font(現在) プライベート API は、見つかったすべてのフォントへのパスのリストを抽出し、すべてのフォントを認識する単一のオブジェクトを構築します。文字列の各グリフは、そのグリフを含むリスト内の最初のフォントを使用してレンダリングされます。

この作業の大部分は、Google Summer of Code 2021 でサポートされている Aitik Gupta によって行われました。