【问题标题】:How to use Font Awesome symbol as marker in matplotlib如何在 matplotlib 中使用 Font Awesome 符号作为标记
【发布时间】:2018-10-20 03:10:34
【问题描述】:

是否可以在 matplotlib 的散点图中使用字体真棒图标作为标记? 或者是否可以将其用作字体并将图标作为“文本”?


这个问题最初被问到here,但由于未知原因被关闭。由于我认为这是一个有效且有用的问题,但 Stackoverflow 上的任何地方都没有解决这个问题并且确实值得回答,所以我会再问一次。

【问题讨论】:

    标签: python matplotlib font-awesome


    【解决方案1】:

    FontAwesome 可从here 获得。 它以矢量图形和 otf-font 的形式提供其图标。

    使用 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()
    

    创建标记

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

    另一种方法是从符号创建matplotlib.path.Path。这可以通过matplotlib.textpath.TextToPath 实例来完成,不幸的是没有记录。 TextToPath 有一个方法get_text_path 以字体属性和字符串作为输入并返回顶点和代码,从中创建PathPath 可以用作 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()
    

    【讨论】:

      【解决方案2】:

      添加 ImportanceOfBeingErnest 的最佳答案:您可以使用 fontawesome Python 包轻松获取 UTF 密钥。

      通过 pip 安装:

      pip install fontawesome
      

      用法:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-08-11
        • 2016-08-14
        • 2021-03-13
        • 2013-10-21
        • 2016-11-13
        • 1970-01-01
        • 2014-01-13
        • 2016-09-21
        相关资源
        最近更新 更多