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



我目前正在尝试将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,因为它总是在一段时间后崩溃。可能文件已经很大了。有什么建议吗?在这种情况下,进一步的缩减采样可能有效,但通常可能不起作用。

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

大型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 图。就是这样:)

最新更新