Plotting only upper/lower triangle of a heatmap
You could plot over one white matrix with upper/lower part transparent
a =random((10,10))
imshow(a, interpolation='nearest')
b = ones(a.shape+(4,)) # «white» matrix with alpha=1
for i in range(a.shape[0]):
for j in range(i, a.shape[1]):
b[i,j,3] = 0 # upper triangle, alpha = 0
imshow(b, interpolation='nearest')
upper/lower triangle of a heatmap http://lh5.ggpht.com/_ZgVr3-a-Z00/S4P3_BWByKI/AAAAAAAAAXE/UsJpokz6LKE/pp.png
import numpy as NP
from matplotlib import pyplot as PLT
from matplotlib import cm as CM
A = NP.random.randint(10, 100, 100).reshape(10, 10)
# create an upper triangular 'matrix' from A
A2 = NP.triu(A)
fig = PLT.figure()
ax1 = fig.add_subplot(111)
# use dir(matplotlib.cm) to get a list of the installed colormaps
# the "_r" means "reversed" and accounts for why zero values are plotted as white
cmap = CM.get_cmap('gray_r', 10)
ax1.imshow(A2, interpolation="nearest", cmap=cmap)
ax1.grid(True)
PLT.show()
The problem with the answer provided by doug is that it relies on the fact that the colormap maps zero values to white. This means that colormaps that do not include white color are not useful. The key for solution is cm.set_bad
function. You mask the unneeded parts of the matrix with None or with NumPy masked arrays and set_bad
to white, instead of the default black. Adopting doug's example we get the following:
import numpy as NP
from matplotlib import pyplot as PLT
from matplotlib import cm as CM
A = NP.random.randint(10, 100, 100).reshape(10, 10)
mask = NP.tri(A.shape[0], k=-1)
A = NP.ma.array(A, mask=mask) # mask out the lower triangle
fig = PLT.figure()
ax1 = fig.add_subplot(111)
cmap = CM.get_cmap('jet', 10) # jet doesn't have white color
cmap.set_bad('w') # default value is 'k'
ax1.imshow(A, interpolation="nearest", cmap=cmap)
ax1.grid(True)
PLT.show()
The best answer i got was from seaborn. The output is a smooth and simple looking figure. This function saves the triangle to local
def get_lower_tri_heatmap(df, output="cooc_matrix.png"):
mask = np.zeros_like(df, dtype=np.bool)
mask[np.triu_indices_from(mask)] = True
# Want diagonal elements as well
mask[np.diag_indices_from(mask)] = False
# Set up the matplotlib figure
f, ax = plt.subplots(figsize=(11, 9))
# Generate a custom diverging colormap
cmap = sns.diverging_palette(220, 10, as_cmap=True)
# Draw the heatmap with the mask and correct aspect ratio
sns_plot = sns.heatmap(data, mask=mask, cmap=cmap, vmax=.3, center=0,
square=True, linewidths=.5, cbar_kws={"shrink": .5})
# save to file
fig = sns_plot.get_figure()
fig.savefig(output)