matplotlib/seaborn: first and last row cut in half of heatmap plot
Unfortunately matplotlib 3.1.1 broke seaborn heatmaps; and in general inverted axes with fixed ticks.
This is fixed in the current development version; you may hence
- revert to matplotlib 3.1.0
- use matplotlib 3.1.2 or higher
- set the heatmap limits manually (
ax.set_ylim(bottom, top) # set the ylim to bottom, top
)
Seaborn heatmap top and bottom row are partially truncated
This issue has been raised and closed on the Seaborn github. The solution found there by ResidentMario & MaozGelbart was:
This was a matplotlib regression introduced in 3.1.1 which has been fixed in 3.1.2 (still forthcoming). For now the fix is to downgrade matplotlib to a prior version.
And later,
Matplotlib 3.1.2 has been released (also available for conda users through conda-forge using conda install -c conda-forge matplotlib=3.1.2). This fixes the issue.
Highlight minimum values every row using seaborn heatmap
You could loop through the rows, find the index of the minimum, and draw a rectangle there. Setting clip_on=False
prevents that the rectangles would be clipped by the border.
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
Pe = np.random.rand(5, 5)
fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(10, 4))
sns.set_style('white')
sns.heatmap(Pe, linewidth=0.5, annot=True, ax=ax1)
for ind, row in enumerate(Pe):
min_col = np.argmin(row)
ax1.add_patch(plt.Rectangle((min_col, ind), 1, 1, fc='none', ec='skyblue', lw=5, clip_on=False))
sns.heatmap(Pe, mask=Pe != Pe.min(axis=1, keepdims=True), annot=True, lw=2, linecolor='black', clip_on=False,
cmap=ListedColormap(['skyblue']), cbar=False, ax=ax2)
plt.tight_layout()
plt.show()
PS: To create animations, the Celluloid library is a lightweight option:
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
import seaborn as sns
import numpy as np
from celluloid import Camera
Pe = np.random.rand(5, 5)
fig, ax1 = plt.subplots()
camera = Camera(fig)
sns.set_style('white')
row_array = np.arange(Pe.shape[0]).reshape(-1, 1)
for row in range(Pe.shape[0]):
sns.heatmap(Pe, mask=(Pe != Pe.min(axis=1, keepdims=True)) | (row < row_array),
annot=True, lw=2, linecolor='black', clip_on=False,
cmap=ListedColormap(['skyblue']), cbar=False, ax=ax1)
camera.snap()
animation = camera.animate(interval=800)
animation.save('animation.gif')
plt.show()
For more complicated animations, matplotlib's animation API can be considered.
Related Topics
Permanently Add a Directory to Pythonpath
How to Count the Frequency of the Elements in an Unordered List
How to Implement an Efficient Infinite Generator of Prime Numbers in Python
Pandas Percentage of Total With Groupby
Python List of Dictionaries Search
How to Send an Email With Gmail as Provider Using Python
Iterating Through a Range of Dates in Python
Add Scrolling to a Platformer in Pygame
Efficient Way to Rotate a List in Python
Error Message: "'Chromedriver' Executable Needs to Be Available in the Path"
Can't Pickle ≪Type 'Instancemethod'≫ When Using Multiprocessing Pool.Map()
How to Calculate Number of Days Between Two Given Dates