R: interactive plots (tooltips): rCharts dimple pl

2020-02-10 06:50发布

I have some charts created with ggplot2 which I would like to embed in a web application: I'd like to enhance the plots with tooltips. I've looked into several options. I'm currently experimenting with the rCharts library and, among others, dimple plots.

Here is the original ggplot:

enter image description here

Here is a first attempt to transpose this to a dimple plot:

enter image description here

I have several issues:

  1. after formatting the y-axis with percentages, the data is altered.

  2. after formatting the x-axis to correctly render dates, too many labels are printed.

I am not tied to dimple charts, so if there are other options that allow for an easier way to tweak axis formats I'd be happy to know. (the Morris charts look nice too, but tweaking them looks even harder, no?)

Objective: Fix the axes and add tooltips that give both the date (in the format 1984) and the value (in the format 40%).

If I can fix 1 and 2, I'd be very happy. But here is another, less important question, in case someone has suggestions:

Could I add the line labels ("Top 10%") to the tooltips when hovering over the lines?

After downloading the data from: https://gist.github.com/ptoche/872a77b5363356ff5399, a data frame is created:

df <- read.csv("ps-income-shares.csv")

The basic dimple plot is created with:

library("rCharts")
p <- dPlot(
    value ~ Year,
    groups = c("Fractile"),
    data = transform(df, Year = as.character(format(as.Date(Year), "%Y"))),
    type = "line",
    bounds = list(x = 50, y = 50, height = 300, width = 500)
)

While basic, so far so good. However, the following command, intended to convert the y-data to percentages, alters the data:

p$yAxis(type = "addMeasureAxis", showPercent = TRUE)

What am I doing wrong with showPercent?

For reference, here is the ggplot code:

library("ggplot2")
library("scales")
p <- ggplot(data = df, aes(x = Year, y = value, color = Fractile))
p <- p + geom_line()
p <- p + theme_bw()
p <- p + scale_x_date(limits = as.Date(c("1911-01-01", "2023-01-01")), labels = date_format("%Y"))
p <- p + scale_y_continuous(labels = percent)
p <- p + theme(legend.position = "none")
p <- p + geom_text(data = subset(df, Year == "2012-01-01"), aes(x = Year, label = Fractile, hjust = -0.2), size = 4)
p <- p + xlab("")
p <- p + ylab("")
p <- p + ggtitle("U.S. top income shares (%)")
p

For information, the chart above is based on the data put together by Thomas Piketty and Emmanuel Saez in their study of U.S. top incomes. The data and more may be found on their website, e.g.

http://elsa.berkeley.edu/users/saez/

http://piketty.pse.ens.fr/en/

EDIT:

Here is a screenshot of Ramnath's solution, with a title added and axis labels tweaked. Thanks Ramnath!

p$xAxis(inputFormat = '%Y-%m-%d', outputFormat = '%Y')
p$yAxis(outputFormat = "%")
p$setTemplate(afterScript = "
  <script>
    myChart.axes[0].timeField = 'Year'
    myChart.axes[0].timePeriod = d3.time.years
    myChart.axes[0].timeInterval = 10
    myChart.draw()
    myChart.axes[0].titleShape.remove()  // remove x label
    myChart.axes[1].titleShape.remove()  // remove y label
    myChart.svg.append('text')           // chart title
        .attr('x', 40)
        .attr('y', 20)
        .text('U.S. top income shares (%)')
        .style('text-anchor','beginning')
        .style('font-size', '100%')
        .style('font-family','sans-serif')
  </script>               
")
p

enter image description here

To change (rather than remove) axis labels, for instance:

myChart.axes[1].titleShape.text('Year')

To add a legend to the plot:

p$set(width = 1000, height = 600)
p$legend(
  x = 580,
  y = 0,
  width = 50,
  height = 200,
  horizontalAlign = "left"
)

To save the rchart:

p$save("ps-us-top-income-shares.html", cdn = TRUE)

An alternative based on the nvd3 library can be obtained (without any of the fancy stuff) with:

df$Year <- strftime(df$Year, format = "%Y")
n <- nPlot(data = df, value ~ Year, group = 'Fractile', type = 'lineChart')

2条回答
Rolldiameter
2楼-- · 2020-02-10 07:41

rCharts is rapidly evolving. I know it is late, but in case someone else would like to see it, here is an almost complete replication of the ggplot sample shown.

  #For information, the chart above is based
  #on the data put together by Thomas Piketty and Emmanuel Saez
  #in their study of U.S. top incomes.
  #The data and more may be found on their website, e.g.
  #http://elsa.berkeley.edu/users/saez/
  #http://piketty.pse.ens.fr/en/

  #read in the data
  df <- read.csv(
    "https://gist.githubusercontent.com/ptoche/872a77b5363356ff5399/raw/ac86ca43931baa7cd2e17719025c8cde1c278fc1/ps-income-shares.csv",
    stringsAsFactors = F
  )

  #get year as date
  df$YearDate <- as.Date(df$Year)

  library("ggplot2")
  library("scales")
  p <- ggplot(data = df, aes(x = YearDate, y = value, color = Fractile))
  p <- p + geom_line()
  p <- p + theme_bw()
  p <- p + scale_x_date(limits = as.Date(c("1911-01-01", "2023-01-01")), labels = date_format("%Y"))
  p <- p + scale_y_continuous(labels = percent)
  p <- p + theme(legend.position = "none")
  p <- p + geom_text(data = subset(df, Year == "2012-01-01"), aes(x = YearDate, label = Fractile, hjust = -0.2), size = 4)
  p <- p + xlab("")
  p <- p + ylab("")
  p <- p + ggtitle("U.S. top income shares (%)")
  gp <- p
  gp


  p <- dPlot(
    value ~ Year,
    groups = c("Fractile"),
    data = df,
    type = "line",
    bounds = list(x = 50, y = 50, height = 300, width = 500)
  )
  p$xAxis(inputFormat = '%Y-%m-%d', outputFormat = '%Y')
  p$yAxis(outputFormat = "%")
  p$setTemplate(afterScript = "
    <script>
       myChart.axes[0].timeField = 'Year'
       myChart.axes[0].timePeriod = d3.time.years
       myChart.axes[0].timeInterval = 5
       myChart.draw() 

       //if we wanted to change  our line width to match the ggplot chart
       myChart.series[0].shapes.style('stroke-width',1);

      //to take even one step further
      //we can add labels like in the ggplot example
      myChart.svg.append('g')
        .selectAll('text')
        .data(
          d3.nest().key(function(d){return d.cx}).map(myChart.series[0]._positionData)[myChart.axes[0]._max])
        .enter()
          .append('text')
          .text(function(d){return d.aggField[0]})
          .attr('x',function(d){return myChart.axes[0]._scale(d.cx)})
          .attr('y',function(d){return myChart.axes[1]._scale(d.cy)})
          .attr('dy','0.5em')
          .style('font-size','80%')
          .style('fill',function(d){return myChart._assignedColors[d.aggField[0]].fill})
     </script>
  ")
  p$defaultColors(ggplot_build(gp)$data[[2]]$colour)
  p
查看更多
Emotional °昔
3楼-- · 2020-02-10 07:47

Here is one way to solve (1) and (2). The argument showPercent is not to add % to the values, but to recompute the values so that they stack up to 100% which is why you are seeing the behavior you pointed out.

At this point, you will see that we are still having to write custom javascript to tweak the x-axis to get it to display the way we want it to. In future iterations, we will strive to allow the entire dimple API to be accessible within rCharts.

df <- read.csv("ps-income-shares.csv")
p <- dPlot(
  value ~ Year,
  groups = c("Fractile"),
  data = df,
  type = "line",
  bounds = list(x = 50, y = 50, height = 300, width = 500)
)
p$xAxis(inputFormat = '%Y-%m-%d', outputFormat = '%Y')
p$yAxis(outputFormat = "%")
p$setTemplate(afterScript = "
  <script>
     myChart.axes[0].timeField = 'Year'
     myChart.axes[0].timePeriod = d3.time.years
     myChart.axes[0].timeInterval = 5
     myChart.draw()

     //if we wanted to change  our line width to match the ggplot chart
     myChart.series[0].shapes.style('stroke-width',1);

   </script>
")
p
查看更多
登录 后发表回答