1

I have a few related questions:

1) I was wondering if there is way of making a heatmap of discrete values in python similar to the example given here.

Once the heatmap is created, I'll need some additional controls:

2) Control the number of row and column labels. Let say, I have two variables x and y where 0 <= x,y <= 1. I somehow compute a function f of x and y (f(x,y)) where the output value of the function is only 1, 2 or 3. Next, I create a nested loop on x and y to compute f for different values of x and y. See the sample pseudocode below:

from __future__ import division
import bumpy as np
    def f(x,y):
        ### Compute the value of f for a given x and y. The output value will be 1, 2 or 3 ###
        f = np.random.randint(1,4)

    data = {}
    for x in [i/100 for i in range(101)]
        for y in [i/100 for i in range(101)]
            data[(x,y)] = f(x,y)

Now, I have a 100x100 matrix of data for which I will make a heatmap s. If I want to show the row and column labels on the heatmap though, 100 points for each row and column will be shown (0, 0.01, 0.02, ..., 1), which makes the figure too crowded. I would like to determine the increment on each axis, e.g., if the increment is 0.2, then the row and column labels should be 0, 0.2, 0.4, 0.6, 0.8 and 1. While this can be easily done for line plots, I was wondering if the same thing can be applied to a heatmap.

3) Control the font size and face of labels.

4) Add gridlines for the horizontal and vertical axis.

user3076813
  • 499
  • 2
  • 6
  • 13

1 Answers1

1

Try heatmap from seaborn.

To actually store tabular data I wouldn't use a dictionary. A list of list would be better, but the best way to go is using NumPy arrays (see also: numpy - evaluate function on a grid of points).

import numpy as np
import pandas as pd
import seaborn as sns

X = np.linspace(0, 1, 101)
Y = np.linspace(0, 1, 101)

data = np.zeros((101, 101))

# or use meshgrid instead
for i, x in enumerate(X):
    for j, y in enumerate(Y):
        data[i, j] = some_function(x, y)

df = pd.DataFrame(data, index=Y, columns=X)

sns.heatmap(df)

Alternatively, you can use imshow (see: imshow when you are plotting data, not images. Realtion between aspect and extent?) - then it will show only some ticks on the axes.

Community
  • 1
  • 1
Piotr Migdal
  • 11,864
  • 9
  • 64
  • 86
  • heatmap from seaborn seems to be able to do most of what I need, but I have difficulties figuring out how to tell heatmap use e.g., Green for 1, yellow for 2 and 3 for red and to show these labels in the color bar (similarly to the example for the ggplot2 in the link I gave earlier). Another problem that I have is that the labels of the vertical axis start with 0.00 on the top and 1.00 in the bottom. How can I reverse this order (i.e., to show 0.00 in the bottom and 1.00 on the top like a linear plot)? – user3076813 Aug 19 '15 at 20:18
  • @user3076813 For colors - it uses `cmap` parameter - search how to make it for discrete values. – Piotr Migdal Aug 19 '15 at 21:50
  • I got the color bar to work but I had to use matshow (not sns.heatmap). The only problem that I have now is that I'd like to get the xtick and ytick labels in the middle of gridlines (similarly to sns.heatmap). Ticklables are correctly placed in the center by matshow but the gridlines are always drawn from where the ticklabels are located. How can I make them to be placed on both sides of the ticklables? I checked this post: http://stackoverflow.com/questions/24190858/matplotlib-move-ticklabels-between-ticks . The 1st method doesn't work for matshow and the 2nd works only for minor gridlines. – user3076813 Aug 20 '15 at 21:48