[R] Smooth contour of a map

David Winsemius dwinsemius at comcast.net
Wed May 18 15:18:50 CEST 2011


You may be looking for the par settings of xaxs="i", yaxs="i", which  
if you add them to the plot call will prevent the "regular" behavior  
of adding 4% padding to the axis widths.

?par

-- David.

On May 18, 2011, at 8:27 AM, Pierre Bruyer wrote:

> I've pratically resolved my problem (the code is under that), but a  
> last thing is not perfect:
> when I use the function plot to call after the function polygon,  
> there is a marge between my raster and the window. I think it's the  
> axis of the function "plot()", but I have not found how delete it.  
> Someone have a solution please?
>
> Pierre Bruyer
>
> ##smooth contour
> 	
> 	contours <- contourLines(V2b,levels=paliers)
>
> 	
> 	par(mar=c(0,0,0,0))
> 	plot(1,col="white",main="polygon()", asp = 1, axes = FALSE, ann =  
> FALSE,xlim=c(0,1), ylim = c(0,1),type = "n", method = c("image"))
> 	for (i in seq_along(contours)) {
> 		 x <- contours[[i]]$x
> 		 y <- contours[[i]]$y
> 		 c <- contours[[i]]$level
> 		 j <- 1
> 		 tmp <- 0
> 		 while(j < length(level[,1]) && tmp == 0){
> 		 	if(level[j,1] == c){
> 		 		tmp <- j
> 		 	}
> 		 	j <- j+1
> 		}	
>
> 		polygon( spline( seq_along(x), x)$y, spline( seq_along(y), y) 
> $y ,col = colgraph[tmp+1], border = NA)
> 	}
>
>
>
> Le 17 mai 2011 à 16:44, Pierre Bruyer a écrit :
>
>> The result is good, thanks a lot, but how can I with this method  
>> fill my raster to color?
>>
>> Le 17 mai 2011 à 15:43, Duncan Murdoch a écrit :
>>
>>> I don't think filled.contour gives you access to the contour  
>>> lines.  If you use contourLines() to compute them, then you can  
>>> draw them using code like this:
>>>
>>> contours <- contourLines(V2b,levels=paliers)
>>> for (i in seq_along(contours)) {
>>> x <- contours[[i]]$x
>>> y <- contours[[i]]$y
>>> lines( splines( seq_along(x), x)$y, splines( seq_along(y), y)$y )
>>> }
>>>
>>> but as I said, you won't get great results.  A better way is to  
>>> use a finer grid, e.g. by fitting a smooth surface to your set of  
>>> points and using predictions from the model to interpolate.
>>>
>>> Duncan Murdoch
>>>
>>>
>>> On 17/05/2011 9:35 AM, Pierre Bruyer wrote:
>>>> I work with large datasets (10000 points) so I can't post them ,  
>>>> but my function is :
>>>>
>>>> create_map<- function(grd, level ,map_output, format = c("jpeg"),  
>>>> width_map = 150, height_map = 150,...)
>>>> {	
>>>> 		
>>>> 	##sp<- spline(x = grd[,1], y = grd[,2])
>>>>
>>>> 	grd2<- matrix(grd[,3], nrow = sqrt(length(grd[,3])), ncol =  
>>>> sqrt(length(grd[,3])), byrow = FALSE)
>>>> 	
>>>> 	V2b<- grd2
>>>>
>>>> 	
>>>> 	##creation of breaks for colors
>>>> 	i<-1	
>>>> 	paliers<- c(-1.0E300)
>>>> 	while(i<=length(level[,1]))
>>>> 	{
>>>> 		paliers<- c(paliers,level[i,1])
>>>> 		i<- i+1
>>>> 	}
>>>> 	paliers<- c(paliers, 1.0E300)
>>>> 		
>>>> 	##scale color creation
>>>> 	i<- 1
>>>> 	colgraph<- c(rgb(255,255,255, maxColorValue = 255))
>>>> 	while(i<=length(level[,2]))
>>>> 	{
>>>> 		colgraph<- c(colgraph, rgb(level[i,2],level[i,3],level[i,4],  
>>>> maxColorValue = 255))
>>>> 		i<- i +1
>>>> 	}
>>>>
>>>> 	##user can choose the output format (default is jpeg)
>>>> 	switch(format,
>>>> 		png = png(map_output, width = width_map, height = height_map) ,
>>>> 		jpeg = jpeg(map_output, width = width_map, height = height_map,  
>>>> quality = 100),
>>>> 		bmp = bmp(map_output, width = width_map, height = height_map),
>>>> 		tiff = tiff(map_output, width = width_map, height = height_map),
>>>> 		jpeg(map_output, width = width_map, height = height_map))
>>>>
>>>> 	## drawing map
>>>> 	
>>>> 	##delete marge
>>>> 	par(mar=c(0,0,0,0))
>>>> 	filled.contour(V2b, col = colgraph, levels = paliers, asp = 1,  
>>>> axes = FALSE, ann = FALSE)
>>>> 	dev.off() 		
>>>>
>>>> }
>>>>
>>>> where grd is a xyz data frame,
>>>> map_output is the path+name of the output image file,
>>>> and level is a matrix like this :
>>>>
>>>>
>>>> level<- matrix(0,10,4)
>>>> level[1,1]<- 1.0000E+00
>>>> level[2,1]<- 3.0000E+00
>>>> level[3,1]<- 5.0000E+00
>>>> level[4,1]<- 1.0000E+01
>>>> level[5,1]<- 1.5000E+01
>>>> level[6,1]<- 2.0000E+01
>>>> level[7,1]<- 3.0000E+01
>>>> level[8,1]<- 4.0000E+01
>>>> level[9,1]<- 5.0000E+01
>>>> level[10,1]<- 7.5000E+01
>>>>
>>>>
>>>> level[1,2]<- 102
>>>> level[2,2]<- 102
>>>> level[3,2]<- 102
>>>> level[4,2]<- 93
>>>> level[5,2]<- 204
>>>> level[6,2]<- 248
>>>> level[7,2]<- 241
>>>> level[8,2]<- 239
>>>> level[9,2]<- 224
>>>> level[10,2]<- 153
>>>>
>>>> level[1,3]<- 153
>>>> level[2,3]<- 204
>>>> level[3,3]<- 204
>>>> level[4,3]<- 241
>>>> level[5,3]<- 255
>>>> level[6,3]<- 243
>>>> level[7,3]<- 189
>>>> level[8,3]<- 126
>>>> level[9,3]<- 14
>>>> level[10,3]<- 0
>>>>
>>>> level[1,4]<- 153
>>>> level[2,4]<- 204
>>>> level[3,4]<- 153
>>>> level[4,4]<- 107
>>>> level[5,4]<- 102
>>>> level[6,4]<- 33
>>>> level[7,4]<- 59
>>>> level[8,4]<- 63
>>>> level[9,4]<- 14
>>>> level[10,4]<- 51
>>>>
>>>> Le 17 mai 2011 à 15:17, Duncan Murdoch a écrit :
>>>>
>>>>> On 17/05/2011 8:24 AM, Pierre Bruyer wrote:
>>>>>> Thank you for your answer, but the function spline() (and a lot  
>>>>>> of other function in R)  can't take in its parameters the  
>>>>>> original contour which are define by a vector, i.e. :
>>>>>>
>>>>>
>>>>> If you post some reproducible code to generate the contours,  
>>>>> someone will show you how to use splines to interpolate them.
>>>>>
>>>>> Duncan Murdoch
>>>>>
>>>>>> 	##creation of breaks for colors
>>>>>> 	i<-1	
>>>>>> 	paliers<- c(-1.0E300)
>>>>>> 	while(i<=length(level[,1]))
>>>>>> 	{
>>>>>> 		paliers<- c(paliers,level[i,1])
>>>>>> 		i<- i+1
>>>>>> 	}
>>>>>> 	paliers<- c(paliers, 1.0E300)
>>>>>>
>>>>>>
>>>>>>
>>>>>> Le 17 mai 2011 à 13:05, Duncan Murdoch a écrit :
>>>>>>
>>>>>>> On 11-05-17 5:58 AM, Pierre Bruyer wrote:
>>>>>>>> I'm a French developer (so I am sorry if my english is not  
>>>>>>>> perfect). I have a problem to smooth the contours of a map. I  
>>>>>>>> have a dataset with 3 columns, x, y and z, where x and y are  
>>>>>>>> the coordinates of my points and z is evaluate to a  
>>>>>>>> qualitative elevation and his representation is a set of  
>>>>>>>> colors, which is define by levels.
>>>>>>>>
>>>>>>>> The problem is the curve of my contour is so linear, and I  
>>>>>>>> would like a more continuous contour. I use the function  
>>>>>>>> fitted.contour to draw my map.
>>>>>>>
>>>>>>> If you use a finer grid of x,y values you'll get shorter  
>>>>>>> segments and they will look smoother.
>>>>>>>
>>>>>>> You might be able to use a smooth interpolator (e.g. spline())  
>>>>>>> rather than linear interpolation, but those occasionally do  
>>>>>>> strange things e.g.
>>>>>>>
>>>>>>> x<- c(1:4, 5.9, 6:10)
>>>>>>> y<- c(1:4,   7, 6:10)
>>>>>>> plot(spline(x,y, n=200), type="l")
>>>>>>> points(x,y)
>>>>>>>
>>>>>>> where one point is out of line with the others, but the curve  
>>>>>>> overcompensates in order to stay smooth.
>>>>>>>
>>>>>>> Duncan Murdoch
>>>>>>
>>>>>
>>>>
>>>
>>
>
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.

David Winsemius, MD
Heritage Laboratories
West Hartford, CT



More information about the R-help mailing list