如何在Matplotlib中使用Font Awesome符号作为标记

时间:2018-10-20 03:10:34

标签: python matplotlib font-awesome

是否可以在matplotlib的散点图中使用超棒的字体图标作为标记? 还是可以将其用作字体,然后将图标作为“文本”放置?


该问题最初是由here提出的,但由于未知原因而被关闭。由于我认为这是一个有效且有用的问题,Stackoverflow上尚未解决任何问题,并且肯定值得您回答,因此我将再次询问。

2 个答案:

答案 0 :(得分:7)

FontAwesome可从here获得。 它提供其图标作为矢量图形和otf字体。

使用FontAwesome otf字体

Matplotlib无法本地读取矢量图形,但是it can load otf-fonts。 下载FontAwesome软件包后,您可以通过matplotlib.font_manager.FontProperties对象访问字体,例如

fp = FontProperties(fname=r"C:\Windows\Fonts\Font Awesome 5 Free-Solid-900.otf") 

创建文本

FontProperties可以作为matplotlib文本对象的输入

plt.text(.6, .4, "\uf16c", fontproperties=fp)

不幸的是,无法使用FontAwesome ligatures。因此,需要通过其UTF8键访问各个符号。这有点麻烦,但是cheatsheet在这里可以派上用场。将这些需要的符号存储在有意义的名称的字典中可能是有道理的。

示例:

from matplotlib.font_manager import FontProperties
import matplotlib.pyplot as plt

fp1 = FontProperties(fname=r"C:\Windows\Fonts\Font Awesome 5 Brands-Regular-400.otf")
fp2 = FontProperties(fname=r"C:\Windows\Fonts\Font Awesome 5 Free-Solid-900.otf")

symbols = dict(cloud = "\uf6c4", campground = "\uf6bb", hiking = "\uf6ec",
               mountain = "\uf6fc", tree = "\uf1bb", fish = "\uf578",
               stackoverflow = "\uf16c")

fig, (ax, ax2) = plt.subplots(ncols=2, figsize=(6.2, 2.2), sharey=True)
ax.text(.5, .5, symbols["stackoverflow"], fontproperties=fp1, size=100, 
         color="orange", ha="center", va="center")


ax2.stackplot([0,.3,.55,.6,.65,1],[.1,.2,.2,.2,.2,.15],[.3,.2,.2,.3,.2,.2],
              colors=["paleturquoise", "palegreen"])
ax2.axis([0,1,0,1])
ax2.text(.6, .4, symbols["mountain"], fontproperties=fp2, size=16, ha="center")
ax2.text(.09, .23, symbols["campground"], fontproperties=fp2, size=13)
ax2.text(.22, .27, symbols["hiking"], fontproperties=fp2, size=14)
ax2.text(.7, .24, symbols["tree"], fontproperties=fp2, size=14,color="forestgreen")
ax2.text(.8, .33, symbols["tree"], fontproperties=fp2, size=14,color="forestgreen")
ax2.text(.88, .28, symbols["tree"], fontproperties=fp2, size=14,color="forestgreen")
ax2.text(.35, .03, symbols["fish"], fontproperties=fp2, size=14,)
ax2.text(.2, .7, symbols["cloud"], fontproperties=fp2, size=28,)

plt.show()

enter image description here

创建标记

创建很多像上面这样的文本并不是很方便。将图标用作标记对于某些应用程序会更好。 Matplotlib确实具有使用utf符号作为标记的功能,但是只能通过mathtext功能使用。在我的试用中,无法将otf字体用作matplotlib中的mathfont。

另一种方法是从符号创建matplotlib.path.Path。可以通过matplotlib.textpath.TextToPath实例来完成此操作,不幸的是,该实例没有文档说明。 TextToPath具有方法get_text_path,该方法将fontproperty和字符串作为输入并返回用于创建Path的顶点和代码。 Path可以用作marker,例如scatter图。

v, codes = TextToPath().get_text_path(fp, \uf6fc)
path = Path(v, codes, closed=False)
plt.scatter(..., marker=path)

一些例子:

import numpy as np; np.random.seed(32)
from matplotlib.path import Path
from matplotlib.textpath import TextToPath
from matplotlib.font_manager import FontProperties
import matplotlib.pyplot as plt

fp = FontProperties(fname=r"C:\Windows\Fonts\Font Awesome 5 Free-Solid-900.otf")

symbols = dict(cloud = "\uf6c4", campground = "\uf6bb", hiking = "\uf6ec",
               mountain = "\uf6fc", tree = "\uf1bb", fish = "\uf578",
               stackoverflow = "\uf16c")

fig, ax = plt.subplots()

def get_marker(symbol):
    v, codes = TextToPath().get_text_path(fp, symbol)
    v = np.array(v)
    mean = np.mean([np.max(v,axis=0), np.min(v, axis=0)], axis=0)
    return Path(v-mean, codes, closed=False)

x = np.random.randn(4,10)
c = np.random.rand(10)
s = np.random.randint(120,500, size=10)
plt.scatter(*x[:2], s=s, c=c, marker=get_marker(symbols["cloud"]), 
            edgecolors="none", linewidth=2)
plt.scatter(*x[2:], s=s, c=c, marker=get_marker(symbols["fish"]), 
            edgecolors="none", linewidth=2)   

plt.show()

enter image description here

答案 1 :(得分:0)

补充ImportanceOfBeingErnest 的精彩回答:您可以使用fontawesome Python 包轻松获取UTF 密钥。

通过 pip 安装:

pip install fontawesome

用法:

import fontawesome as fa

# icons dict converts to correct utf-8 code:
fa.icons['thumbs-up']