2 votes

Existe-t-il un moyen efficace de stocker des tracés 2D sous forme de graphique vectoriel en python ?

J'essaie actuellement de stocker des tracés python sous forme de graphiques vectoriels pour améliorer leur apparence dans un document latex. Pour les tracés 1D, cela fonctionne très bien :

import numpy as np
import matplotlib as mpl
mpl.use('svg')
new_rc_params = {
    "font.family": 'Times',
    "font.size": 12,
    "font.serif": [],
    "svg.fonttype": 'none'} #to store text as text, not as path
mpl.rcParams.update(new_rc_params)
import matplotlib.pyplot as plt

x = np.linspace(-.5, .5, 1024)

plt.figure()
plt.plot(x, x)
plt.title('\$x = y\$')
plt.xlabel('\$x\$ [m]')
plt.ylabel('\$y\$ [m]')
plt.savefig('test.svg', format = 'svg', bbox_inches = 'tight')

De cette façon, je peux ouvrir le fichier svg dans inkscape et le convertir en pdf/pdf_tex et chaque texte du tracé sera rendu en latex dans le document --> même police et taille de police que partout ailleurs dans le document.

Les tracés 2D deviennent incroyablement gros en tant que fichiers svg. C'est pourquoi je veux stocker le tracé en pdf (encore une fois, je veux garder le texte en tant que texte. C'est pourquoi je ne peux pas stocker le tracé en .png) :

mpl.use('pdf')
new_rc_params = {
    "font.family": 'Times',
    "font.size": 12,
    "font.serif": []
    }
    #"svg.fonttype": 'none'} #not needed here since we don't use svg anymore
mpl.rcParams.update(new_rc_params)
import matplotlib.pyplot as plt

x = np.linspace(-.5, .5, 1024)
x, y = np.meshgrid(x, x)
z = np.exp(-(x**2 + y**2))

plt.figure()
plt.title('Gaussian plot: \$z = \exp{-(x^2 + y^2)}\$')
plt.pcolormesh(x, y, z)
plt.colorbar()
plt.savefig('test.pdf', bbox_inches='tight', format='pdf')

Cela permet de stocker le tracé 2D sous forme de pdf. Quoi qu'il en soit, le stockage du tracé prend un certain temps maintenant et il devient assez gros (même avec seulement 500 x 500 points dans le tracé, il fait environ 11 Mo). Mais, le texte est stocké en tant que texte.

Malheureusement je ne peux pas ouvrir le pdf dans inkscape maintenant, car il se plante toujours après un certain temps. Probablement que le fichier est déjà trop gros. Des suggestions ? Un sous-échantillonnage supplémentaire pourrait fonctionner dans ce cas, mais probablement pas en général.

1voto

Forrest Thumb Points 76

Voici une réponse que j'ai suggérée dans les commentaires :

Les gros fichiers pdf/svg résultent du stockage de chaque rectangle dans pcolormesh comme un graphique vectoriel.

Ce que je voulais obtenir en stockant le tracé au format svg/pdf, c'était d'obtenir une image haute résolution où le texte est rendu une fois que j'ai inséré le fichier dans mon document latex. Le tracé lui-même n'a pas vraiment besoin d'être un graphique vectoriel si la résolution est suffisamment bonne.

Voici donc ma suggestion (les bibliothèques importées sont les mêmes que ci-dessus) :

mpl.use('svg')
new_rc_params = {
    "font.family": 'Times', #probably python doesn't know Times, but it will replace it with a different font anyway. The final decision is up to the latex document anyway
    "font.size": 12, #choosing the font size helps latex to place all the labels, ticks etc. in the right place
    "font.serif": [],
    "svg.fonttype": 'none'} #to store text as text, not as path
mpl.rcParams.update(new_rc_params)

plt.figure(figsize = (6.49/2, 6.49/2)) #that's about half the text width of an A4 document
plt.pcolormesh(x, y, z, rasterized = True) # That's the trick. It will render the image already in python!
plt.xlabel('Math expression: \$a + b = c\$') # We need the backslashes because otherwise python will render the mathematic expression which will confuse latex
plt.savefig('test.svg', dpi = 1000, format = 'svg', bbox_inches = 'tight') # depends on your final figure size, 1000 dpi should be definitely enough for A4 documents

Une fois que vous avez enregistré le fichier svg, ouvrez-le dans Inkscape. Enregistrez-le au format pdf et cochez la case "Omettre le texte dans le PDF et créer un fichier LaTex". Dans votre fichier latex, vous devez utiliser

\begin{figure}
    \centering
    \input{test.pdf_tex}
    \caption{This should have the same font type and size as your xlabel}
\end{figure}

pour importer votre tracé 2D. C'est tout :)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X