I'm trying to plot a heatmap with seaborn and export it to pgf for easy import in Latex. This works more or less, the only thing that is bothering me is that the bar for the colours is exported as an extra png.
So if I run the export to pgf I get the following:
This is definitely undesirably as a png is not scaling well. Some 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')
And the content of test.csv:
0,1,2,3,4
1,1,1,1,1
2,2,2,2,2
3,3,3,3,3
Does anyone have a solution to include the colour bar into the pgf output?
To create a nice screenshot of your heatmap can be challenging especially on your mobile or small device. You can now click the 💾 button on the heatmap to save the map as an image. The map will scale to selected size using the center and zoom level. So you can create a larger screenshot then your screen.
I discovered some peculiarities in the libraries that export to pgf/tikz.
First, in matplotlib
, the quadmesh (i.e. the heatmap) is exported correctly to pgf, but the colorbar is exported as png (what the op encountered).
I tried the same thing with the matplotlib2tikz
library. in this case, the quadmesh is exported as a png, but the colormap can be exported correctly. However, If you suppress the heatmap, for example by plotting the colormap to a separate Axes
and clearing the heatmap axes, the colorbar is exported as png.
So if you combine the output of two exports, you can have them both.
The heatmap:
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')
Note that I suppress the plotting of the colorbar with cbar=False
Then get the colorbar:
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)
The solution now requires some dirty work. I am aware that this is really not good practice, but this is the only way I could find.
In the colormap.tex
file, you need to delete all the lines except the ones needed for the colormap.
The beginnings of colormap.tex
:
\begin{tikzpicture}
\begin{axis}[
... % definition of axis: delete these lines
colorbar,
colormap={mymap}{[1pt]
...
So that you get this:
\begin{tikzpicture}
\begin{axis}[
hide axis,
colorbar,
colormap={mymap}{[1pt]
...
At the end of the file, delete everything between the closing of the square brackets and \end{axis}
:
]
... %delete these lines
\end{axis}
This change in the file can be automatised, I included an example in the code on github
In your main tex file, you can add these two figures
\input{heatmap_nocbar.pgf}
\input{colorbar.tex}
If you want a full working example and full outputs, I have put everything from this answer on github.
This is probably far from a perfect answer for you, but I lack the python skills to dive deeper in the backends of matplotlib
and matplotlib2tikz
to give a nicer example.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With