Reputation: 37
I'm trying to make a 1D heatmap for a gene (see ref 1 in pastebin for example). I've gotten close to what I'm looking for with contourf, but I haven't been able to figure out how to get exactly what I'm looking for. Basically, I'm want to utilize a colormap that has 10 discrete colors, and the cutoffs for the different colors correspond to the percentiles of the data (so the top 10% of the data points are red, the next 10% are orange, etc).
I don't have enough reputation to post more than two links or any images, so you can also see my output images from the code below, as well as the other pages I've looked at to try and solve this question, at http://pastebin.com/jAkxyQsK.
The actual data points are in a list at http://pastebin.com/3TrkkpZ0. You can try with random integers, but the difference between linear scaling and percentile-scaling likely won't be clear unless your data is skewed like mine.
data = [] #actually a list of ~450 floats
x = []
nd = np.array(data)
x = np.empty([2, nd.shape[0]])
x[:,:] = nd
fig = plt.figure(figsize = (11, 8.5))
ax = fig.add_subplot(111)
Now, here are my experiments:
mind, maxd, sprd = min(data), max(data), max(data)-min(data)
levels = [(lambda n: mind + (n*sprd)/10)(n) for n in range(0,11,1)]
hm = plt.contourf(x, levels = levels, cmap = "rainbow")
cbar = fig.colorbar(hm, ax = ax)
plt.show()
[Figure 1 on pastebin]
This is mostly what I want to see: the colorbar is discretized and the plot looks fine, but the colorbar is spaced linearly between the max and the min of the data, which is not what I want. Attempt two:
levels = np.percentile(data, [z for z in range (0,110,10)])
hm = plt.contourf(x, levels = levels, cmap = "rainbow")
cbar = fig.colorbar(hm, ax = ax)
plt.show()
[Figure 2 on pastebin]
This is also close; the colorbar is divided up by the values of the percentiles (or at least the tick values indicate that), but for some reason it's no longer utilizing the full range of the colormap and I have no idea why.
I also tried implementing the function described in references 2 and 3 with pcolor, but I couldn't figure out how to make them work with my data instead of a scatter plot and the results were not as close as I could get with contourf, so I stopped pursuing them. If the answer is already in one of the links I've looked at but I couldn't understand it, then a 'plain English' translation would be super helpful.
Upvotes: 3
Views: 1159
Reputation: 98
I cannot tell why the colormap does not use the full range of colors in your example, but it seems that the following is closer to the result you want (i.e. it does span a larger range of colors with the quantile levels).
...
hm = plt.contourf(x, levels = levels, cmap = "rainbow", vmax = levels[-2])
...
You can also try a 'weighted' value for the max colormap level.
...
hm = plt.contourf(x, levels = levels, cmap = "rainbow", vmax = 0.3 * levels[-1] + 0.7 * levels[-2])
...
Upvotes: 1