简体   繁体   中英

How to Draw a three-dimensional graph in R

f(x,y)= (1/25)*(20-x)/x   10<x<20, x/2 <y <x
        0                   o.t

I have to create this image through this expression. 在此处输入图片说明

but 在此处输入图片说明

x <- seq(10, 20, length=20)
y <- seq(10, 20, length=20)
f <- function(x,y){(1/25)*(20-x)/5}
z <- outer(x,y,f)
persp(x,y,z,theta=30,phi=30, expand=0.5,col=rainbow(19), border=NA)

what is wrong?

You should mask z based on the constraint. As a suggestion, you can use an amazing interactive rgl package in R.

#source: https://stackoverflow.com/questions/50079316/plot3d-how-to-change-z-axis-surface-color-to-heat-map-color
map2color <- function(x, pal, limits = range(x,na.rm=T)){
  pal[findInterval(x, seq(limits[1], limits[2], length.out = length(pal) + 1), 
               all.inside=TRUE)]
}

x <- seq(10, 20, length=20)
y <- seq(10, 20, length=20)
mask <- sapply(x,function(m) sapply(y,function(n) if((n>m/2)&(n<m)){(1/25)*(20-m)/5}else{ NA }))
z <- outer(x,y,f)
z <- z * mask
#persp(x,y,z, col= map2color(z, rainbow(100)),border = NA)
library(rgl)
persp3d(x,y,z,col = map2color(z, rainbow(100)),theta=30,phi=30)

在此处输入图片说明 在此处输入图片说明

@SRhm's answer is probably the best choice, but if you want to live on the bleeding edge, you can get rid of the jagged diagonal edge using a development version of rgl (from R-forge), at least version 0.100.8.

This version supports triangulations with boundaries using the tripack package. So you set up a grid of values over the xy range, then define the boundaries of the region using the equations, and you get smooth edges. For example:

library(tripack)
library(rgl)
g <- expand.grid(x=10:20, y=5:20)
keep <- with(g, 10 < x & x < 20 & x/2 < y & y < x)
g2 <- g[keep,]
tri <- tri.mesh(g2)

# Set up boundary constraints
cx <- c(10:20, 20: 10)
cy <- c(seq(5, 10, len=11), 20:10)
tri2 <- add.constraint(tri, cx, cy, reverse = TRUE)

# This isn't necessary, but shows where the formula will be evaluated
plot(tri2)

三角剖分

It might be better to fill in some of the left and right edges with more points to avoid those big triangles, but skip that for now.

z <- with(tri2, (1/25)*(20-x)/x)
# Now plot it, using the map2color function @SRhm found:
#source: https://stackoverflow.com/questions/50079316/plot3d-how-to-change-z-axis-surface-color-to-heat-map-color
map2color <- function(x, pal, limits = range(x,na.rm=T)){
  pal[findInterval(x, seq(limits[1], limits[2], length.out = length(pal) + 1), 
               all.inside=TRUE)]
}
persp3d(tri2, z, col = map2color(z, rainbow(100)))

After rotation, you get this view:

persp3d视图

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM