Подтвердить что ты не робот

Оси в минимальной степени, без прокладки, на участках растровых * объектов

Есть ли способ убедиться, что поле вокруг сюжета точно соответствует растровым экстентам? В нижеследующем есть пробел сверху или снизу или слева и справа от растра в зависимости от пропорций устройства:

require(raster)
r = raster()
r[]= 1
plot(r, xlim=c(xmin(r), xmax(r)), ylim=c(ymin(r), ymax(r)))

Одним из элементов проблемы с растровыми объектами является asp=1 для обеспечения правильного отображения. Следующая базовая диаграмма рассеяния имеет такую ​​же проблему, когда asp=1:

plot(c(1:10), c(1:10), asp=1)

Попробуйте vectorplot(r) из пакета rasterVis, чтобы посмотреть, как я хочу, чтобы оси выглядели.

EDIT:

Решения должны хорошо сочетаться с наложениями SpatialPoints, не отображая точек за пределами указанных растровых ограничений:

require(raster)
require(maptools)

# Raster
r = raster()
r[]= 1

# Spatial points
x = c(-100, 0, 100)
y = c(100, 0, 100)
points = SpatialPoints(data.frame(x,y))

plot(r, xlim=c(xmin(r), xmax(r)), ylim=c(ymin(r), ymax(r)))
plot(points, add=T)
4b9b3361

Ответ 1

Вероятно, вам лучше всего пойти с одной из функций lattice для построения пространственных растровых объектов, предоставляемых пакетами raster и rasterVis. Вы обнаружили один из них в vectorplot(), но spplot() или levelplot() лучше соответствуют вашим потребностям в этом случае.

(Метод base graphics plot() plot() для объектов "RasterLayer" просто не позволяет вам легко установить оси с соответствующим соотношением сторон. Для всех, кого это интересует, я подробно расскажу о том, почему поэтому в разделе внизу сообщения.)

В качестве примера вида графика, который levelplot() производит:

require(raster)
require(rasterVis)

## Create a raster and a SpatialPoints object.
r <- raster()
r[] <- 1:ncell(r)
SP <- spsample(Spatial(bbox=bbox(r)), 10, type="random")

## Then plot them    
levelplot(r, col.regions = rev(terrain.colors(255)), cuts=254, margin=FALSE) +
layer(sp.points(SP, col = "red"))

## Or use this, which produces the same plot.
# spplot(r, scales = list(draw=TRUE), 
#        col.regions = rev(terrain.colors(255)), cuts=254) +
# layer(sp.points(SP, col = "red"))

enter image description here

Любой из этих методов может по-прежнему отображать некоторую часть символа, представляющего точки, которые попадают прямо за пределы графического графика. Если вы хотите избежать этой возможности, вы можете просто подсечь свой объект SpatialPoints, чтобы удалить любые точки, находящиеся за пределами растра. Вот простая функция, которая сделает это для вас:

## A function to test whether points fall within a raster extent
inExtent <- function(SP_obj, r_obj) {
    crds <- [email protected]
    ext  <- extent(r_obj)
    crds[,1] >= [email protected]  &  crds[,1] <= [email protected] &
    crds[,2] >= [email protected]  &  crds[,2] <= [email protected]
}
## Remove any points in SP that don't fall within the extent of the raster 'r'
SP <- SP[inExtent(SP, r), ]

Дополнительные более мелкие детали о том, почему трудно сделать plot(r) производить плотно прилегающие оси

Когда plot вызывается на объект типа raster, растровые данные (в конечном счете) отображаются с использованием либо rasterImage(), либо image(). Какой путь следует за ним, зависит от: (a) типа устройства, на которое построено; и (b) значение аргумента useRaster в исходном вызове plot().

В любом случае область построения настраивается таким образом, который создает оси, которые заполняют область построения, а не таким образом, что дает им соответствующее соотношение сторон.

Ниже я показываю цепочку функций, которая вызвала путь к этому шагу, а также вызов, который в конечном итоге устанавливает область построения. В обоих случаях, как представляется, нет простого способа изменить как масштаб, так и соотношение сторон осей, которые нанесены на график.

  • useRaster=TRUE

    ## Chain of functions dispatched by `plot(r, useRaster=TRUE)`
    getMethod("plot", c("RasterLayer", "missing"))
    raster:::.plotraster2
    raster:::.rasterImagePlot
    
    ## Call within .rasterImagePlot() that sets up the plotting region
    plot(NA, NA, xlim = e[1:2], ylim = e[3:4], type = "n",
               , xaxs = "i", yaxs = "i", asp = asp, ...)
    
    ## Example showing why the above call produces the 'wrong' y-axis limits
    plot(c(-180,180), c(-90,90), 
         xlim = c(-180,180), ylim = c(-90,90), pch = 16,
         asp = 1,
         main = "plot(r, useRaster=TRUE) -> \nincorrect y-axis limits")
    
  • useRaster=FALSE

    ## Chain of functions dispatched by `plot(r, useRaster=FALSE)`
    getMethod("plot", c("RasterLayer", "missing"))
    raster:::.plotraster2
    raster:::.imageplot
    image.default
    
    ## Call within image.default() that sets up the plotting region
    plot(NA, NA, xlim = xlim, ylim = ylim, type = "n", xaxs = xaxs, 
         yaxs = yaxs, xlab = xlab, ylab = ylab, ...)
    
    ## Example showing that the above call produces the wrong aspect ratio
    plot(c(-180,180), c(-90,90), 
         xlim = c(-180,180), ylim = c(-90,90), pch = 16,
         main = "plot(r,useRaster=FALSE) -> \nincorrect aspect ratio")
    

Ответ 2

Человек, я был в тупике и в итоге просто превратил цвет переднего плана в сюжет. Тогда вы можете воспользоваться тем фактом, что метод растровой графики вызывает fields:::image.plot, что позволяет просто нарисовать легенду (второй раз, на этот раз показывая чернила!). Это неэлегантно, но в этом случае работает:

    par("fg" = NA)
    plot(r, xlim = c(xmin(r), xmax(r)), ylim = c(ymin(r), ymax(r)), axes = FALSE)
    par(new = TRUE,"fg" = "black")
    plot(r, xlim = c(xmin(r), xmax(r)), ylim = c(ymin(r), ymax(r)), axes = FALSE, legend.only = TRUE)
    axis(1, pos = -90, xpd = TRUE)
    rect(-180,-90,180,90,xpd = TRUE)
    ticks <- (ymin(r):ymax(r))[(ymin(r):ymax(r)) %% 20 == 0]
    segments(xmin(r),ticks,xmin(r)-5,ticks, xpd = TRUE)
    text(xmin(r),ticks,ticks,xpd=TRUE,pos=2)
        title("sorry, this could probably be done in some more elegant way")

enter image description here

Ответ 3

Вот так я решил эту проблему

require(raster)
r = raster()

# default for raster is 180 row by 360 cols =  64800 cells
# fill with some values to make more interesting
r[]= runif(64800, 1, 1000)

# Set margin for text
par(mar=c(2, 6, 6, 2))

# Set some controls for the raster cell colours and legend

MyBrks<-c(0,1,4,16,64,256,1E20)                                  
MyLbls<-c("<1","<4","<16","<64","<256","<Max")       
MyClrs<-c("blue","cyan","yellow","pink","purple","red")  

# Plot raster without axes or box or legend
# Note xlim and ylim don't seem do much unless you want to trim x and y
plot(r, 
     col=MyClrs,
     axes=FALSE,
     box=FALSE,
     legend=FALSE
     )

# Set up the ranges and intervals for axes - you can get the min max
# using xmin(r) and ymax(r) and so on if you like
MyXFrm <- -180
MyXTo <- 180
MyXStp <- 60
MyYFrm <- -90
MyYTo <- 90
MyYStp <- 30

# Plot the axes
axis(1,tick=TRUE,pos=ymin(r),las=1,at=seq(MyXFrm,MyXTo ,MyXStp )) 
axis(2,tick=TRUE,pos=xmin(r),las=1,at=seq(MyYFrm ,MyYTo ,MyYStp ))

# Plot the legend use xpd to plot the legend outside the plot region
par(xpd=TRUE)
legend(MyXTo ,MyYTo , 
       legend=MyLbls[1:6],                    
       col= MyClrs,             
       fill=Clrs[1:6],                            
       bg=rgb(0,0,0,0.85),           
       cex=0.9,
       text.col="white",
       text.font=2,                      
       border=NA                 
      ) 

# Add some axis labels and a title
text(-220,0,"Y",font=2)
text(0,-130,"X",font=2) 
text(0,120,"My Raster",font=4,cex=1.5) 

Как выглядит сюжет

Ответ 4

Я думаю, что лучшим (или самым простым) решением является использование image():

library(raster)

# Raster
r = raster()
r[]= rnorm(ncell(r))

# Spatial points
x = c(-100, 0, 100)
y = c(100, 0, 100)
points = SpatialPoints(data.frame(x,y))

# plot
image(r)
plot(points, add=T, pch=16, cex=2)

растровый график с функцией изображения