【问题标题】:Export seaborn heatmap to full pgf将 seaborn 热图导出到完整的 pgf
【发布时间】:2017-11-22 19:27:12
【问题描述】:

我正在尝试使用 seaborn 绘制热图并将其导出到 pgf 以便在 Latex 中轻松导入。这或多或少有效,唯一困扰我的是颜色栏导出为额外的 png。

因此,如果我将导出运行到 pgf,我会得到以下信息:

  • test.pgf
  • test-img0.png

这绝对是不可取的,因为 png 不能很好地缩放。 一些 MWE:

import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns

df = pd.DataFrame.from_csv("test.csv", sep=',')

sns.set('paper', 'white', rc={'font.size': 10, 'axes.labelsize': 10, 'legend.fontsize': 8, 'axes.titlesize': 10,
                              'xtick.labelsize': 8,
                              'ytick.labelsize': 8, "pgf.rcfonts": False})
plt.rc('font', **{'family': 'serif', 'serif': ['Times']})
plt.rc('text', usetex=True)
fig = plt.figure()
ax = sns.heatmap(df, linewidths=.5)
fig.savefig('test.pdf')
fig.savefig('test.pgf')

以及test.csv的内容:

0,1,2,3,4
1,1,1,1,1
2,2,2,2,2
3,3,3,3,3

有没有人可以将颜色条包含到 pgf 输出中?

【问题讨论】:

  • 我在 python 2.7 和 python 3.5 中的 seaborn 0.7.0 和 matplotlib 1.5.1 上测试了你的代码。通过乳胶运行 pgf 输出给了我一个带有颜色条的漂亮图形。您可以在问题中包含您的输出吗?
  • 我猜代码工作正常。但是 OP 的问题是他们希望在 pgf 输出中包含test-img0.png,而不是作为单独的 png 文件。
  • 我走得太快了,感谢@ImportanceOfBeingErnest 指出这一点!

标签: python matplotlib heatmap seaborn pgf


【解决方案1】:

我在导出到 pgf/tikz 的库中发现了一些特性。

首先,在matplotlib 中,quadmesh(即热图)正确导出到 pgf,但颜色条导出为 png(操作遇到的内容)。

我用matplotlib2tikz 库尝试了同样的事情。在这种情况下,quadmesh 导出为 png,但可以正确导出颜色图。但是,如果您抑制热图,例如通过将颜色图绘制到单独的 Axes 并清除热图轴,则颜色条将导出为 png。

因此,如果您合并两个导出的输出,则可以同时拥有它们。

热图:

import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
df = pd.DataFrame.from_csv("test.csv", sep=',')

sns.set('paper', 'white',
        rc={'font.size': 10, 'axes.labelsize': 10,
            'legend.fontsize': 8, 'axes.titlesize': 10,
            'xtick.labelsize': 8,'ytick.labelsize': 8, 
            "pgf.rcfonts": False,
           })
plt.rc('font', **{'family': 'serif', 'serif': ['Times']})
plt.rc('text', usetex=True)
fig, ax = plt.subplots(figsize=(6,6))
ax = sns.heatmap(df, linewidths=.5, ax=ax, cbar=False)
fig.savefig('heatmap_nocbar.pgf')

请注意,我使用 cbar=False 禁止绘制颜色条

然后获取颜色条:

import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
from matplotlib2tikz import save as tikz_save

df = pd.DataFrame.from_csv("test.csv", sep=',')

sns.set('paper', 'white',
        rc={'font.size': 10, 'axes.labelsize': 10,
            'legend.fontsize': 8, 'axes.titlesize': 10,
            'xtick.labelsize': 8,'ytick.labelsize': 8, 
            "pgf.rcfonts": False,
           })
plt.rc('font', **{'family': 'serif', 'serif': ['Times']})
plt.rc('text', usetex=True)
fig, ax = plt.subplots()
ax = sns.heatmap(df, linewidths=.5, ax=ax, )
tikz_save('colormap.tex', figure=fig, strict=True)

解决方案现在需要一些肮脏的工作。我知道这确实不是一个好习惯,但这是我能找到的唯一方法。

colormap.tex 文件中,您需要删除除颜色图所需的行之外的所有行。

colormap.tex的开端:

\begin{tikzpicture}

\begin{axis}[

... % definition of axis: delete these lines

colorbar,
colormap={mymap}{[1pt]
...

这样你就明白了:

\begin{tikzpicture}

\begin{axis}[
hide axis,
colorbar,
colormap={mymap}{[1pt]
...

在文件末尾,删除方括号结束和\end{axis}之间的所有内容:

]
... %delete these lines
\end{axis}

文件中的这种更改可以自动化,我在github的代码中包含了一个示例

在你的主tex文件中,你可以添加这两个数字

\input{heatmap_nocbar.pgf}
\input{colorbar.tex}

如果您想要一个完整的工作示例和完整的输出,我已将此答案中的所有内容放在github

这对你来说可能远非一个完美的答案,但我缺乏 python 技能来深入研究matplotlibmatplotlib2tikz 的后端以提供一个更好的例子。

【讨论】:

  • 我有点预料到这并不容易。我会试试你的解决方案。不过,自动合并文件肯定会有所改进。
  • 我写了一个快速代码 sn-p 来从 colorbar.tex 中提取线条,@Patrick。您可以在 github 存储库中找到它(答案中的链接)
猜你喜欢
  • 1970-01-01
  • 2020-07-21
  • 1970-01-01
  • 2020-08-04
  • 1970-01-01
  • 2017-10-30
  • 2021-04-14
  • 2018-05-15
  • 2015-09-12
相关资源
最近更新 更多