Search code examples
rplotlypolar-coordinates

R Plotly Polar Equation Rose Curve Graph Issue


I am trying to graph polar equations in R using plotly. However, when I graph a rose curve, I'm not getting the right amount of petals in the graph.

My code...

library(plotly)

f <- function(){
   output <- matrix(ncol=2, nrow = 361)
   for (i in 0:360){
        output[i,1] <- i
       output[i,2] <- 3 * cos(2 * (i * pi/180))
   }
   return(output)
 }
 mf <- f()
 df <- data.frame("theta" = mf[,1], "r"=mf[,2])

 p <- plot_ly(
     df,
     type = 'scatterpolar',
     mode = 'lines'
   ) %>%
   add_trace(
     r = ~r,
     theta = ~theta,
     name = 'Function',
     line = list(
        color = 'red'
    )
   ) %>%
   layout(
      title = 'Polar Graph',
      font = list(
        family = 'Arial',
        size = 12,
        color = '#000'
      ),
      showlegend = F
 )
 p

Resulting graph...

Graph

What the graph should resemble...

Graph

Can anyone tell me what I'm doing wrong or if there's an easier way to do this in R? Thanks.


Solution

  • For common polar plot, I am used to the center having zero radius, but in your case the center of the plot has -3 as radius. Therefor you don’t get the expected result when using plot_lt(). it is possible that plot_lt() allow you to change this in the configuration, but I couldn’t find it.

    A possible solution is to shift the angels and radius such that the radius is always larger than zero. This is done in the function “shift_center_zero” below. For every negative radius, multiply by -1 to make positive, and for those rows make an angle shift such that the radius is on the other side of the center. The angle shift is done by adding half a round (180 degrees) and take modulus of a complete round (360 degrees) to restrict the angle such that it is within a single round.

    shift_center_zero <- function(m){
          m_negative <- m[,2]<0 # get negative rows
          m[m_negative,1] <- (m[m_negative,1]+180)%%360 # angle shift
          m[m_negative,2] <- -1*m[m_negative,2] # radius shift
          return(m)
        }
    

    The rest of your code is pretty much the same, with nrow = 360 insted of 361 to remove NA's and the use of the new "shift_center_zero" function.

    library(plotly)
    
    f <- function(){
      output <- matrix(ncol=2, nrow = 360)
      for (i in 0:360){
        output[i,1] <- i
        output[i,2] <- 3 * cos(2 * (i * pi/180))
      }
      return(output)
    }
    mf <- f()
    
    # make the shift
    mf<-shift_center_zero(mf)
    
    df <- data.frame("theta" = mf[,1], "r"=mf[,2])
    
    
    p <- plot_ly(
      df,
      type = 'scatterpolar',
      mode = 'lines'
    ) %>%
      add_trace(
        r = ~r,
        theta = ~theta,
        name = 'Function',
        line = list(
          color = 'red'
        )
      ) %>%
      layout(
        title = 'Polar Graph',
        font = list(
          family = 'Arial',
          size = 12,
          color = '#000'
        ),
        showlegend = F
      )
    p
    

    The resulting plot