简体   繁体   中英

Shiny R: Plot another column of data on scatterplot using ggplot2

I currently have a scatterplot showing only one column from my data set, which I'm reading from a csv. I want to plot both ATI and BTI.

PP  BTI     ATI
1   9710    9660
2   10000   9900
3   10300   10100
4   10600   10400
.
.
.
99  159000  107000  

My code looks like this:

#server.R

#Income Percentile Scatterplot
incomedata <- read.csv("/Users/mathewsayer/Documents/Work/Level 7/Shiny Flat Tax/Flat Tax App/data/incomedist.csv")

ranges <- reactiveValues(x = NULL, y = NULL)

output$plot1 <- renderPlot({
  ggplot(incomedata, aes(x = BTI, y = PP)) + 
    geom_point() + 
    coord_cartesian(xlim = ranges$x, ylim = ranges$y)
})

#Brush and zoom on scatterplot
observeEvent(input$plot1_dblclick, {
  brush <- input$plot1_brush
  if (!is.null(brush)) {
    ranges$x <- c(brush$xmin, brush$xmax)
    ranges$y <- c(brush$ymin, brush$ymax)
  }
  else {
    ranges$x <- NULL
    ranges$y <- NULL
  }
})

I've tried adding ATI like this: aes(x = BTI:ATI, y = PP) but I get the error message Aesthetics must be either length 1 or the same as the data (99): x, y

Would I be better calling my data as a frame or table? Any help would be greatly appreciated.

EDIT: The black plot points are BTI, I want to the data from ATI to appear similar to this photo-mock up I just done. 完成后的外观示例

I am not sure why you want the percentiles to be on the y-axis, but here is code that does what you want:

library(dplyr)
library(shiny)
library(tidyr)
library(ggplot2)

# simulate some data 
df_foo = data_frame(
  percentile = seq.int(99),
  ATI = sort(rnorm(99)),
  BTI = sort(rnorm(99))
)

# UI
ui_foo = shinyUI(
  plotOutput("plot_foo")
)

# server
server_foo = shinyServer(function(input, output) {
  output$plot_foo = renderPlot({
    df_foo %>% 
    gather(key = var_name, value = value, -percentile) %>% 
    ggplot(aes(x = value, y = percentile, group = var_name, color = var_name)) + 
    geom_line() + 
    theme_bw()
  })
})

# run the server
shinyApp(ui = ui_foo, server = server_foo)

Your question is more fundamentally about how to plot multiple variables in ggplot2 and you need to basically specify the group aesthetic in suitably reshaped data.

In order to plot both BTI and ATI , you need to define which one is plotted on which axis. In other words, you should tell ggplot that you would like both columns plotted, this is missing in your code, ie in ggplot(incomedata, aes(x = BTI, y = PP)) . In this code you are asking BTI to be plotted on x axis and PP on y axis, and as far as I understand you do not want PP to be plotted at all.

Can you please try the code below and see if it does what you are expecting?

ggplot(incomedata, aes(x = BTI, y = ATI)) + 
    geom_point() + 
    coord_cartesian(xlim = ranges$x, ylim = ranges$y)

Thanks for your help bert and tchakravarty.

I reshaped my data into long format and it worked perfectly.

So what I did was:

  • Reshape my data into long format as @Bert suggested with a new Category column

  • Changed my ggplot() to this:

output$plot1 <- renderPlot({ ggplot(incomedata, aes(x = Income, y = PP)) + geom_point(aes(colour=Category, group=Category)) + coord_cartesian(xlim = ranges$x, ylim = ranges$y) })

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