1

I have a pathology image of size 1024 x 1360. I have probability values of some areas and coordinate points. How can I write a code for heatmap generation using the coordinate points and probability values over an image. The details of the probability values (.csv) file format are given below. Any help will be highly appreciated.

Edit:

CSV file format Download .csv file

Content of CSV file:

(x,y)        (x, y+y1)    (x+x1, y)    (x+x1, y+y1) Probability value
(0,0)        (0, 5)       (10, 0)      (10, 5)      0.5
(50,45)      (50, 65)     (55, 45)     (55, 65)     0.9
(100, 150)   (100, 200)   (120, 150)   (120, 200)   0.3
(1000, 1005) (1000, 1010) (1005, 1005) (1005, 1010) 1

Sample imageover which Heatmap should be generated [![Download the image here][2]][2]

Expected Heatmap type [![The generated Heatmap over images should be like this][3]][3]

Generated Results after applying @Paradox's code [![generated output][4]][4]

Additional clarification:

"p" is the probability value of having cancer or not in that particular area. I have extracted all the patches of size 256 x 256 from whole slide images and computed "probability values" of each patch. Now based on that value I'm planning to generate the heatmap. But by using your code I'm getting output like above. Even the color bar is missing. Please help.

user1410665
  • 719
  • 7
  • 23
  • Can you please post the actual text values instead of an image? – Nathaniel Mar 23 '19 at 19:08
  • @Nathaniel Thanks for your response. I have updated my query and given the downloadable link. I'm new in this domain. Please help me. – user1410665 Mar 23 '19 at 19:43
  • 1
    Can you explain the meaning of the columns in the CSV? In row 3 the `Probability value` is 3, which does not seem right. – Rohit Namjoshi Mar 23 '19 at 20:13
  • @RohitNamjoshi This is just a sample data. You can change the probability value to 0.3 – user1410665 Mar 23 '19 at 20:15
  • What about the rest of the rows / columns what do they represent? – Rohit Namjoshi Mar 23 '19 at 20:16
  • x,y, x+x1, y+y1 are the coordinate points. It's like four corners of a rectangle. Withing that area all pixel values are corresponding probability value – user1410665 Mar 23 '19 at 20:20
  • I am still puzzled by the `probability` value of 3. – Paradox Mar 24 '19 at 18:55
  • I have changed the probability value in the .csv file. Probability value will be 0.3 – user1410665 Mar 24 '19 at 19:37
  • Still, they are weirdly represented, have duplicate information and the data are deeply-nested, even if it is unnecessary, as far as I can tell from the sample data file. – Paradox Mar 24 '19 at 21:13
  • I could come up with an answer but, as you asked your question, it seems you just want some rectangles with probability values as a heatmap, or as weights over the pixels values. In any case, that would make a strange image, especially since there is not a probability value for every pixel, according to your "sample data". – Paradox Mar 24 '19 at 23:49
  • **I don't want rectangles with probability values.** Actually I want to generate a heatmap like the "Expected Heatmap Image". The data I have shared here only few samples. There are many more like this. I have coordinate values and probability values based on that I want to generate **Expected Heatmap Image**. – user1410665 Mar 25 '19 at 01:08
  • It would **way** easier to help you out and, more importantly, we can provide you with a working solution if you had provided everything from the start. It may not seem like much but your information were sparse and fuzzy for people not right in front of your datasets. Maybe you could go easy here, we're just trying to help and don't forget SO is here to help others as well. – Paradox Mar 25 '19 at 03:08

1 Answers1

1

Clean your data generating the heatmap

First, if you are not comfortable with deep-nested data, you should clean your data in your CSV file (they are not uniform and have duplicates - they are also error-prone if you want rectangles).

The simplest example being the following:

 x, y, x1, y1, Probability value
 0, 0, 5, 10, 0.5
 50, 45, 55, 65, 0.9
 100, 150, 120, 200, 0.3
 1000, 1005, 1005, 1010, 1

The answer below has been written with this clean CSV dataset in mind.

Use Pandas to process CSV data files

Seeing what your use case is, I recommend using pandas in order to process your CSV data files.

You can store data from a CSV file in a pandas DataFrame this way:

df = pd.read_csv("data.csv")

and iterate over rows, using the first row as keys for each column value, as following:

for index, row in df.iterrows():
    print(row["x"], row["y"], row["x1"], row["y1"], 
      row["Probability value"]         

Full working snippet

This snippet is not very pretty but it works for the dummy dataset you've provided and is intended to be pretty self-explanatory with the above introduction. Some tweaking might be needed, especially for the plotting part.

#!/usr/bin/python3
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from skimage import io
from skimage.color import rgb2gray
import matplotlib as mpl
# Read original image
img = io.imread('img.jpg')

# Get the dimensions of the original image
x_dim, y_dim, z_dim = np.shape(img)

# Create heatmap
heatmap = np.zeros((x_dim, y_dim), dtype=float)

# Read CSV with a Pandas DataFrame
df = pd.read_csv("data.csv")

# Set probabilities values to specific indexes in the heatmap
for index, row in df.iterrows():
    x = np.int(row["x"])
    y = np.int(row["y"])
    x1 = np.int(row["x1"])
    y1 = np.int(row["y1"])
    p = row["Probability value"]
    heatmap[x:x1,y:y1] = p

# Plot images
fig, axes = plt.subplots(1, 2, figsize=(8, 4))
ax = axes.ravel()

ax[0].imshow(img)
ax[0].set_title("Original")
fig.colorbar(ax[0].imshow(img), ax=ax[0])

ax[1].imshow(img, vmin=0, vmax=1)
ax[1].imshow(heatmap, alpha=.5, cmap='jet')
ax[1].set_title("Original + heatmap")

# Specific colorbar
norm = mpl.colors.Normalize(vmin=0,vmax=2)
N = 11
cmap = plt.get_cmap('jet',N)
sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm)
sm.set_array([])
plt.colorbar(sm, ticks=np.linspace(0,1,N), 
             boundaries=np.arange(0,1.1,0.1)) 

fig.tight_layout()
plt.show()
user1410665
  • 719
  • 7
  • 23
Paradox
  • 738
  • 12
  • 30
  • Just a small change: `print(row["x"], row["y"], row["x1"], row["y1"], row["p"])`. Thanks a lot. The code is working. – user1410665 Mar 25 '19 at 14:58
  • You've changed the CSV data file? Otherwise, I do not see where the `p` is coming from. – Paradox Mar 25 '19 at 20:23
  • "p" is the probability value of having cancer or not in that particular area. I have extracted all the patches of size 256 x 256 from whole slide images and computed "probability values" of each patch. Now based on that value I'm planning to generate the heatmap. But by using your code I'm getting output like below above [please check the main question area]. Even the color bar is missing. – user1410665 Mar 25 '19 at 22:01
  • So, `p` is `Probability value` from your CSV file, right? Regarding the plot, you've used the dummy dataset, not the actual one(s) you did not share within your post. Regarding the colorbar, the only thing was to ask for it. All of this should be in the original post. This was actually exactly the kind of "hiccups" I was expecting with a partial question like I said in one of the OP comments. Maybe it would be better if you can come up with the actual and complete problem in your question, if it's too hard for you to come up with the solution with my example on your dummy dataset. – Paradox Mar 25 '19 at 22:33
  • I'm curious to know why only 1 rectangle is visible in the image? number of data points is 4, so 4 rectangles should be generated. please help. – user1410665 Mar 26 '19 at 00:47
  • @user1410665 I'll look at it as soon as I can. – Paradox Mar 26 '19 at 00:49
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/190690/discussion-between-user1410665-and-paradox). – user1410665 Mar 26 '19 at 11:27
  • @user1410665 I fixed my code and made it clearer. Works as expected with the dataset you provided. Sorry for the delay. – Paradox Apr 06 '19 at 20:21
  • Thank you very much it's working. Can you tell me how can I display color bar? I'm trying like below but getting error. `fig.colorbar(heatmap, ax[1], orientation='vertical')` – user1410665 Apr 07 '19 at 03:06
  • Instead of `heatmap` you need to pass `ax[1].imshow(heatmap)`. I updated my code so colormaps are displayed for each plot. Please note that the colormap on the second image is scaled on the probability value. – Paradox Apr 07 '19 at 11:03
  • @Paradox- Thanks a lot. Now the problem is in "Original+heatmap" subplot only heatmap ploting are visible and the background is black. But heatmap should be plotted on the original image. Thanks for bearing with me. – user1410665 Apr 07 '19 at 18:54
  • 1
    This is because the display range is between 0 and 1, which is not the case of the values of the original image. You could deal with that with different methods but the easiest way to have something that works is to change the range of display through `imshow`, like this `ax[1].imshow(img, vmin=0, vmax=1)`. The colorbar needs to be referenced to the image as well. I reflected that in the updated code. Hope you will be happy with the result. Note that it would have been simpler with an actual dataset to see if the achieved result is the same as showed in your question. – Paradox Apr 07 '19 at 20:45