1
$\begingroup$

I'm having a curious issue aligning images and plot, which is mostly working but I'm not sure how to get it fully working. I'm reading in huge image files, and associated CSV files with the (x,y) locations of a particular type of feature. From this csv file, I create a smoothed kernel distribution for where this feature is most likely to be found. I then re-size the image to a width of 800 pixels, then plot the PDF of the smoothed kernel as a contourplot and use image compose to overlay the two. The code looks something like this:

data = Import["centroids.csv"];
w = SmoothKernelDistribution[data, "SheatherJones"];
bringin = Import["output.png"];
k = ImageDimensions[bringin]; 

neww = 800; 
scaleddown = neww/k[[1]];
newh = Round[k[[2]]*scaleddown];
b2 = ImageResize[bringin, {neww, newh}];

cf[z_] := {Opacity[z], Red}
dens4 = ContourPlot[PDF[w, {x, y}] // Evaluate, {x, 1, k[[1]]}, {y, 1, k[[2]]},  PlotRange -> All, PlotPoints -> 50, Contours -> 20, ColorFunction -> cf, BaseStyle -> Directive[Opacity[0.4]], ContourStyle -> Thickness[0.0025], Frame -> None, PlotRangePadding -> None, ImageSize -> {neww, newh}];

step1 = ImageCompose[b2, dens4, {Center, Center}]

In this case k = {8691, 8444} and my output is

Image compose output

This is very close to being correct, but not quite - if I look at dens4, I can see it's not fully 'stretching' to what I've asked it to;

enter image description here

There's a little white-space padding on both extreme sides of the horizontal axes, and thus the plot doesn't precisely line up with the image. This isn't major in this case, but becomes much more marked for other images with greater aspect ratios. Any idea how I can get these two things to play nice? I can provide the re-sized image and raw data for the kernel if it helps, though I suspect I should be able to fix this by either editting the dens4 line or the imagecompose options...

EDIT: In response to request in comments, an MWE with data has been put up here. The sample data required is here and the MWE code is...

 *sample MWE (using resized image)*)
  data = Import["centroids.csv"];
  w = SmoothKernelDistribution[data, "SheatherJones"];
  bringin = Import["b2.png"]; 
  k = {8691, 8444} (*original dimensions*)
  neww = 800; 
  scaleddown = neww/k[[1]];
  newh = Round[k[[2]]*scaleddown];
  cf[z_] := {Opacity[z], Red}
  dens4 = ContourPlot[   PDF[w, {x, y}] // Evaluate, {x, 1, k[[1]]}, {y, 1, 
  k[[2]]}, PlotRange -> All, PlotPoints -> 50, Contours -> 20, 
   ColorFunction -> cf, BaseStyle -> Directive[Opacity[0.4]], 
  ContourStyle -> Thickness[0.0025], Frame -> None, 
   PlotRangePadding -> None, ImageSize -> {neww, newh}];

  step1 = ImageCompose[bringin, dens4, {Center, Center}]
$\endgroup$
  • $\begingroup$ It would help a lot if it was possible to make available data set (could be toy data) that that replicates this problem. $\endgroup$ – C. E. Feb 9 '18 at 16:20
  • 1
    $\begingroup$ Thanks @C.E. - added now. $\endgroup$ – DRG Feb 9 '18 at 18:03
1
$\begingroup$

I think there is no need to use ImageCompose. The function Inset can do the job together with Prolog, and adjusting the AspecRatio of the plot to that of the image:

dens4 = ContourPlot[ PDF[w, {x, y}] // Evaluate, {x, 1, k[[1]]}, {y, 1, k[[2]]}, 
PlotRange -> All, PlotPoints -> 50, Contours -> 15, 
ColorFunction -> cf, ContourStyle -> Thickness[0.0025], 
Frame -> None,PlotRangePadding -> None,AspectRatio -> 8444/8691, 
Prolog -> {Inset[bringin, {0, 0}, {Left, Bottom}, Scaled[1]]}, 
ImageSize -> Large]

enter image description here

Oh, I have use Lighter@Red in cf to make a bit more visible the centroids.

$\endgroup$
  • $\begingroup$ This is absolutely perfect - thank you! Seems inset is a much better option. $\endgroup$ – DRG Feb 19 '18 at 13:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.