Comment utiliser le symbole Impressionnant police comme marqueur dans matplotlib

voix
5

Est-il possible d'utiliser une icône de police-awesome comme marqueur dans un nuage de points avec matplotlib? Ou est-il possible de l'utiliser comme une police et mettre l'icône comme un « texte »?


Cette question a d' abord été posée ici , mais il a été fermé pour une raison inconnue. Depuis que je considère comme un problème valable et utile, qui n'a pas été abordé partout sur Stackoverflow et mérite une réponse sûre, je vais simplement demander à nouveau.

Créé 20/10/2018 à 03:10
source utilisateur
Dans d'autres langues...                            


1 réponses

voix
7

FontAwesome est disponible à partir de . Il fournit ses icônes sous forme de graphiques vectoriels et ainsi que la FEO-police.

Utilisez FontAwesome FTO police

Matplotlib ne peut pas lire nativement des graphiques vectoriels, mais il peut charger FTO-fonts . Après avoir téléchargé le package FontAwesome vous pouvez accéder à la police par l' intermédiaire d' un matplotlib.font_manager.FontPropertiesobjet, par exemple

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

Créer des textes

Le FontPropertiespeut être l'entrée pour les objets texte matplotlib

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

Malheureusement, en utilisant les ligatures FontAwesome est impossible. Par conséquent , les symboles individuels doivent être accessibles par leur clé UTF8. Ceci est un peu lourd, mais le antisèche peut venir ici à portée de main. Le stockage de ces symboles nécessaires dans un dictionnaire avec un nom significatif peut avoir un sens.

Exemple:

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

entrez la description d'image ici

Créer des marqueurs

Création d'un grand nombre de textes comme ci-dessus ne sont pas vraiment à portée de main. Pour avoir les icônes comme marqueurs serait plus agréable pour certaines applications. Matplotlib a la capacité d'utiliser des symboles de utf comme marqueurs, cependant, que par la fonctionnalité mathtext. Obtenir une police FTO à utiliser comme mathfont dans matplotlib a échoué dans mes épreuves.

Une alternative est de créer un à matplotlib.path.Pathpartir du symbole. Cela peut se faire au moyen d' un matplotlib.textpath.TextToPathexemple, qui est malheureusement en situation irrégulière. La TextToPathprésente un procédé get_text_pathprenant une fontproperty et une chaîne en entrée et en retournant les sommets et les codes à partir duquel créer une Path. A Pathpeut être utilisé comme un marqueur , par exemple pour une scatterparcelle.

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

Quelques exemples:

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

entrez la description d'image ici

Créé 20/10/2018 à 03:10
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more