Jeremy
Jeremy

Reputation: 2000

Plotting 2 dimensional function in ggplot

I'd like to plot a function that takes two arguments. The best I've found so far is the image function, but I'd love to find a better either 3d plot or nicer ggplot countour plot like this:

x_seq = seq(1,1000)

y_seq = seq(1,5000)

z = outer(contributor_idx, size_estimate, function(x,y) log(y+1) + log(y+1)/log(x+1))

image(z)

current image

Upvotes: 3

Views: 1386

Answers (2)

eipi10
eipi10

Reputation: 93761

Here's a ggplot version:

library(tidyverse)

# Every 5th value to reduce plotting time for the example
x_seq = seq(1,1000,5)
y_seq = seq(1,5000,5)

z = outer(x_seq, y_seq, function(x,y) log(y+1) + log(y+1)/log(x+1))

colnames(z) = y_seq
rownames(z) = x_seq

# Convert to long format, convert row and column values to numeric, and create groups for colors
dat = as.data.frame(z) %>% 
  rownames_to_column(var="x_seq") %>% 
  gather(y_seq, value, -x_seq) %>% 
  mutate(y_seq=as.numeric(y_seq), 
         x_seq=as.numeric(x_seq),
         value_range = cut(value, 8))

ggplot(dat, aes(x_seq, y_seq, fill=value_range)) + 
  geom_raster() +
  scale_fill_manual(values=colorRampPalette(c("red","orange","yellow"))(8)) +
  theme_classic() +
  guides(fill=guide_legend(reverse=TRUE))

enter image description here

You can do a smooth color gradient also, but it doesn't have enough contrast to be illuminating in this case.

ggplot(dat, aes(x_seq, y_seq, fill=value)) + 
  geom_raster() +
  scale_fill_gradient(low="red", high="yellow") +
  theme_classic()

enter image description here

Upvotes: 3

alistaire
alistaire

Reputation: 43334

plotly has nice support for plotting surfaces (which work better interactively anyway):

library(plotly)

df <- data.frame(x = seq(500),
                 y = seq(500))

z <- outer(df$x, df$y, function(x, y) log(y + 1) + log(y + 1) / log(x + 1))

plot_ly(df, x = ~x, y = ~y, z = ~z) %>% 
    add_surface()

plotly surface

Upvotes: 4

Related Questions