parametric function plot

Hello, all. Is there a way, using ggplot, to make a parametric plot (y(t) versus x(t)) without generating all of the data myself. I want to superimpose a whole bunch of parametric plots, and and generating the data myself, ensuring that it all displays the way I want, would be very tedious. Thanks.

maybe it wouldn't be tedious though ?


myfunc <- function(x){
  x^2
}
myfunc2 <- function(x){
  x^3
}

my_data <- data.frame(x=1:10) %>%
  mutate(myfunc=myfunc(x),
         myfunc2=myfunc2(x)) %>% pivot_longer(
           cols=-x
         )
ggplot(data=my_data,
       mapping=aes(x=x,y=value,color=name)) + 
  geom_line()

image

Thank you for the suggestion, @nirgrahamuk . However, it seems that geom_line does not follow the data in its original, but re-orders it by increasing x values. You happened to choose an example where that doesn't matter because because your x(t) is invertible. I get the following graph, which is not useful, even though it looks kind of cool.

perhaps you can give an example of your function

In this case, I'm looking at logarithmic spirals, e.g. (x(t),y(t))=((1.2)^(0.8t))(cos(t),sin(t))

That's what I've been doing, but it's far from ideal. I was hoping there was a better way.

ok, sorry I can't help.

The issue with ordering of the points can be solved if you use geom_path instead of geom_line. Here's an example:

generate_x <- function(t)
{
  1.2 ^ (0.8 * t) * cos(x = t)
}

generate_y <- function(t)
{
  1.2 ^ (0.8 * t) * sin(x = t)
}

library(ggplot2)

generated_t <- seq(from = 0,
                   to = 2 * pi,
                   by = 0.01)
generated_x <- generate_x(t = generated_t)
generated_y <- generate_y(t = generated_t)

qplot(x = generated_x,
      y = generated_y,
      geom = "path")

However, I do not have a solution where you can plot directly by supplying the two functions. Ther's stat_function, but I don't think it can be used because you want to plot y(t) vs x(t), not just y(t) vs t or x(t) vs t. Combining the two functions may lead to a feasible plot, but that will probably require 3D. I hope someone else will provide a solution for this case.

2 Likes

Not sure exactly what you're looking for, but combining the previous answers, does something like this work? (Using expand_grid to help with generating the data)

library(tidyverse)

myfuncx <- function(t, a, b){
  ((a)^(b*t))*cos(t)
}
myfuncy <- function(t, a, b){
  ((a)^(b*t))*(sin(t))
}

my_data <- expand_grid(t=seq(from=0,to=2*pi,by=0.005), 
                       a = seq(from = 1, to = 1.4, by = 0.1), 
                       b = seq(from = 0.6, to = 1.0, by = 0.1)) %>%
  mutate(x=myfuncx(t, a, b),
         y=myfuncy(t, a, b),
         id = stringr::str_c("a-", a, ":b-", b))  

my_data %>% 
  ggplot(mapping=aes(x=x,y=y,color=id)) + 
    geom_path()

Created on 2020-07-06 by the reprex package (v0.3.0)

Thank you for the tip about geom_path. I wasn't familiar with that function. It does make the graph look much better. I still wish there was something geom_fun that would do it automatically.

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.

just choose an appropriate range of t and use geom_point rather than geom_line


myfuncx <- function(t){
  ((1.2)^(0.8*t))*cos(t)
}
myfuncy <- function(t){
  ((1.2)^(0.8*t))*(sin(t))
}

my_data <- data.frame(t=seq(from=0,to=2*pi,by=0.005)) %>%
  mutate(x=myfuncx(t),
         y=myfuncy(t))  

ggplot(data=my_data,
       mapping=aes(x=x,y=y,color=t)) + 
  geom_point()

image