Экспорт тепловой карты морского побережья в полный pgf

Я пытаюсь построить тепловую карту с seaborn и экспортировать ее в pgf для легкого импорта в латекс. Это работает более или менее, единственное, что меня беспокоит, это то, что панель для цветов экспортируется как дополнительный png.

Так что, если я запускаю экспорт в pgf, я получаю следующее:

  • test.pgf
  • Тест-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?

1 ответ

Я обнаружил некоторые особенности в библиотеках, которые экспортируют в pgf/tikz.

Первый в matplotlib, квадратная сетка (то есть тепловая карта) правильно экспортируется в pgf, но цветовая шкала экспортируется как png (с чем столкнулась операция).

Я попробовал то же самое с matplotlib2tikz библиотека. в этом случае четырехугольник экспортируется как 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

В вашем основном текстовом файле вы можете добавить эти две цифры

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

Если вам нужен полный рабочий пример и полные результаты, я выложил все из этого ответа на github.

Это, вероятно, далеко не идеальный ответ для вас, но мне не хватает навыков Python, чтобы погрузиться глубже в бэкэнды matplotlib а также matplotlib2tikz чтобы дать более хороший пример.

Другие вопросы по тегам