Reputation: 441
I'm trying to make a plot similar to this one.
This is similar to a heat map, but clearly different since the colour doesn't correspond to a count. I made this one using a geom_point() with very small differences between individual traces.
library(tidyverse)
data = crossing(
x = seq(-1, 1, by = 0.01),
a = seq(1, 5, by = 0.01)
) %>%
mutate(y = a*x^2)
ggplot(data, aes(x = x, y = y, colour = a)) +
geom_point() +
labs(title = "Plot of y = ax^2")
Clearly is this less than ideal since it takes a lot of time and generates a data set of over 80k rows. I'm sure there's a better way to do this. Any thoughts? Thanks.
EDIT: Based on @Axeman's comment, I used geom_raster. A naive version doesn't work, though, namely
ggplot(data, aes(x = x, y = y, fill = a)) +
geom_raster()
The result is the error
Error in matrix(NA_character_, nrow = nrow, ncol = ncol) : invalid 'nrow' value (too large or NA) In addition: Warning message: In f(...) : NAs introduced by coercion to integer range
It looks like it has something to do with there not being every combination of x
and y
. It does work if I switch a
and y
in the code. Using that information, this code generates what I'm looking for in this specific case.
data = crossing(
x = seq(-1, 1, by = 0.01),
y = seq(0, 5, by = 0.01)
) %>%
mutate(a = y/(x^2)) %>%
filter(a <= 5 & a >= 1)
ggplot(data, aes(x = x, y = y, fill = a)) +
geom_raster()
It works a lot faster, but it requires me to solve the equation I want to plot for a
. I don't think this would scale well with complex equations, nor with empirical data. There's got to be a better way.
Upvotes: 0
Views: 363
Reputation: 441
Firstly, need to use geom_raster
(thanks @Axeman). Secondly, the link (https://github.com/tidyverse/ggplot2/issues/2516) shared by @Chris seems to demonstrate my problem, even though I'm using the latest ggplot2 package (3.1.0).
So in the end, this code works:
library(tidyverse)
data_bad = crossing(
x = seq(-1, 1, by = 0.01),
a = seq(1, 5, by = 0.01)
) %>%
mutate(y = a*x^2)
ggplot(data_bad, aes(x = round(x,2), y = round(y,2), fill = a)) +
geom_raster()
The only problem is that you need to match the rounding number to the precision of your data, otherwise the plot has a lot of white-space in the middle.
But this solution works enough. Thanks for the help.
Upvotes: 0