有没有一种有效的方法将2D图存储为python中的矢量图形?

时间:2018-05-24 09:44:18

标签: python matplotlib vector-graphics inkscape

我目前正在尝试将python图存储为矢量图形,以改善它们在乳胶文档中的外观。对于1D图,这非常好:

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

这样我可以在inkscape中打开svg文件并将其转换为pdf / pdf_tex,并且图中的每个文本都将在文档中以乳胶呈现 - >与文档中的其他位置相同的字体和字体大小。

2D绘图作为svg文件变得越来越大。因此,我想将该图存储为pdf(同样,我希望将文本保存为文本。这就是为什么我不能将该图存储为.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')

这将2D图存储为pdf。无论如何,存储情节现在需要一段时间并且它变得非常大(即使在情节中只有500 x 500点它大约11 MB)。但是,文本存储为文本。

不幸的是我现在无法在inkscape中打开pdf,因为它会在一段时间后崩溃。可能该文件已经很大了。有什么建议?在这种情况下,进一步的下采样可能会起作用,但可能不是一般的。

1 个答案:

答案 0 :(得分:1)

以下是我在评论中建议的答案:

大型pdf / svg文件是将pcolormesh中的每个矩形存储为矢量图形的结果。

将图存储为svg / pdf时我想要实现的是获取高分辨率图像,一旦我将文件插入到我的乳胶文档中,文本就会呈现。如果分辨率足够好,情节本身并不需要是矢量图形。

所以这是我的建议(导入的库与上面相同):

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

存储svg文件后,在Inkscape中打开它。保存为pdf并在“在PDF中省略文本并创建LaTex文件”中设置勾号。在您的乳胶文件中,您必须使用

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

导入2D绘图。就是这样:))