Seaborn Heatmap without lines between cells
Question:
I´m trying to create a heatmap with seaborn with a transparent colormap since an image should be displayed in the background. The heatmap creation works fine so far, however some lines between the cells are still visible even though the linewidth of the heatmap is set to 0.0.
The code for the creation of the heatmap looks like the following:
ax = sns.heatmap(image, cmap="rocket_r", linewidths=0.0)
ax.collections[0].set_alpha(0.5)
Where image
is 64×64 numpy array. The resulting heatmap looks like this:
Heatmap (sorry not enough repuation for embedding pictures)
The problem are the thin lines between the cells. Strangely they aren´t at every edge.
Anyone knows how to get rid of those lines?
Many Thanks
Update 1 (Complete working example):
image = np.array([[1, 1, 2, 2], [3, 3, 3, 3], [4, 5, 4, 5], [6, 6, 6, 6]])
ax = sns.heatmap(image, cmap="rocket_r", linewidths=0.0)
ax.collections[0].set_alpha(0.5)
plt.show()
Results is this heatmap:
Here you can see that there are thin lines between every column but there isn´t any line between the first and second row.
Answers:
The lines are the overlapping of semitransparent patches which cannot be perfectly aligned on the pixel grid.
alpha blending
An option is to not use transparency, but instead create opaque colors with alpha blending.
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
import numpy as np
import seaborn as sns
def get_alpha_blend_cmap(cmap, alpha):
cls = plt.get_cmap(cmap)(np.linspace(0,1,256))
cls = (1-alpha) + alpha*cls
return ListedColormap(cls)
image = np.array([[1, 1, 2, 2], [3, 3, 3, 3], [4, 5, 4, 5], [6, 6, 6, 6]])
ax = sns.heatmap(image, cmap=get_alpha_blend_cmap("rocket_r", 0.5), linewidths=0.0)
plt.show()
An obvious advantage of this is that the colorbar has the same colors as the heatmap.
increase dpi
If the above is not an option you may increase the dpi when saving.
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
image = np.array([[1, 1, 2, 2], [3, 3, 3, 3], [4, 5, 4, 5], [6, 6, 6, 6]])
ax = sns.heatmap(image, cmap="rocket_r", linewidths=0.0, edgecolor="none", alpha=0.5)
plt.savefig("test.png", dpi=1000)
This does of course not have any effect on the figure shown on screen though.
imshow
Finally, consider not using seaborn here, but instead a matplotlib imshow
plot.
import matplotlib.pyplot as plt
import seaborn as sns
plt.style.use("seaborn-dark")
plt.rcParams["axes.facecolor"] = "white"
import numpy as np
image = np.array([[1, 1, 2, 2], [3, 3, 3, 3], [4, 5, 4, 5], [6, 6, 6, 6]])
im = plt.imshow(image, cmap="rocket_r", alpha=0.5)
plt.colorbar(im)
plt.gca().set(xticks=(range(image.shape[1])),yticks=(range(image.shape[0])))
plt.show()
I have just come across this problem. I need to upload the plot to overleaf, so I do not like the dpi solutions. Here is what I came up with, based on the solution of OP:
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
image = np.array([[1, 1, 2, 2], [3, 3, 3, 3], [4, 5, 4, 5], [6, 6, 6, 6]])
ax = sns.heatmap(image, cmap="rocket_r", linewidths=0.1)
colors = ax.collections[0].get_facecolors()
ax.collections[0].set_edgecolors(colors)
plt.imshow()
The idea is to create a thin edge around each cell with the cell’s facecolor. This removes the lines without changing the original cell colors.
I´m trying to create a heatmap with seaborn with a transparent colormap since an image should be displayed in the background. The heatmap creation works fine so far, however some lines between the cells are still visible even though the linewidth of the heatmap is set to 0.0.
The code for the creation of the heatmap looks like the following:
ax = sns.heatmap(image, cmap="rocket_r", linewidths=0.0)
ax.collections[0].set_alpha(0.5)
Where image
is 64×64 numpy array. The resulting heatmap looks like this:
Heatmap (sorry not enough repuation for embedding pictures)
The problem are the thin lines between the cells. Strangely they aren´t at every edge.
Anyone knows how to get rid of those lines?
Many Thanks
Update 1 (Complete working example):
image = np.array([[1, 1, 2, 2], [3, 3, 3, 3], [4, 5, 4, 5], [6, 6, 6, 6]])
ax = sns.heatmap(image, cmap="rocket_r", linewidths=0.0)
ax.collections[0].set_alpha(0.5)
plt.show()
Results is this heatmap:
Here you can see that there are thin lines between every column but there isn´t any line between the first and second row.
The lines are the overlapping of semitransparent patches which cannot be perfectly aligned on the pixel grid.
alpha blending
An option is to not use transparency, but instead create opaque colors with alpha blending.
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
import numpy as np
import seaborn as sns
def get_alpha_blend_cmap(cmap, alpha):
cls = plt.get_cmap(cmap)(np.linspace(0,1,256))
cls = (1-alpha) + alpha*cls
return ListedColormap(cls)
image = np.array([[1, 1, 2, 2], [3, 3, 3, 3], [4, 5, 4, 5], [6, 6, 6, 6]])
ax = sns.heatmap(image, cmap=get_alpha_blend_cmap("rocket_r", 0.5), linewidths=0.0)
plt.show()
An obvious advantage of this is that the colorbar has the same colors as the heatmap.
increase dpi
If the above is not an option you may increase the dpi when saving.
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
image = np.array([[1, 1, 2, 2], [3, 3, 3, 3], [4, 5, 4, 5], [6, 6, 6, 6]])
ax = sns.heatmap(image, cmap="rocket_r", linewidths=0.0, edgecolor="none", alpha=0.5)
plt.savefig("test.png", dpi=1000)
This does of course not have any effect on the figure shown on screen though.
imshow
Finally, consider not using seaborn here, but instead a matplotlib imshow
plot.
import matplotlib.pyplot as plt
import seaborn as sns
plt.style.use("seaborn-dark")
plt.rcParams["axes.facecolor"] = "white"
import numpy as np
image = np.array([[1, 1, 2, 2], [3, 3, 3, 3], [4, 5, 4, 5], [6, 6, 6, 6]])
im = plt.imshow(image, cmap="rocket_r", alpha=0.5)
plt.colorbar(im)
plt.gca().set(xticks=(range(image.shape[1])),yticks=(range(image.shape[0])))
plt.show()
I have just come across this problem. I need to upload the plot to overleaf, so I do not like the dpi solutions. Here is what I came up with, based on the solution of OP:
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
image = np.array([[1, 1, 2, 2], [3, 3, 3, 3], [4, 5, 4, 5], [6, 6, 6, 6]])
ax = sns.heatmap(image, cmap="rocket_r", linewidths=0.1)
colors = ax.collections[0].get_facecolors()
ax.collections[0].set_edgecolors(colors)
plt.imshow()
The idea is to create a thin edge around each cell with the cell’s facecolor. This removes the lines without changing the original cell colors.