bokeh / rbokeh

R interface to Bokeh http://hafen.github.io/rbokeh/
Other
313 stars 67 forks source link

Hide legend in ly_bar and add hover function #144

Open SixiangHu opened 8 years ago

SixiangHu commented 8 years ago

hi hafen

thanks for creating this rbokeh package, which is fascinating.

I have 2 questions about ly_bar: 1: Is there any method to hide the legend in ly_bar? 2: How to add hover to ly_bar?

Thanks.

An example is like:

a <- sample(LETTERS[1:5],100,replace=TRUE)
b <- sample(LETTERS[1:5],100,replace=TRUE)
c<- data.frame(aa=a,bb=b)

figure() %>% ly_bar(aa,color=bb,data=c)
hafen commented 8 years ago

I added support for hiding the legend (in any plot) by doing figure(legend_location = NULL) %>% ....

This fix is here: https://github.com/hafen/rbokeh/tree/dev. There's a lot of work in there I'm still vetting so I haven't pushed to the main repo yet.

Hover for ly_bar could be difficult. It would be easy to automatically add a hover with the count/sum for each bar, but for a custom hover, since the data doesn't map directly to the rectangles being drawn, I'd have to think about it.

SixiangHu commented 8 years ago

Thanks @hafen, that's really quick. :+1:

cddesja commented 8 years ago

@hafen, any update on the second request here to add a hover for the bars?

hafen commented 8 years ago

I have added hover for bars (on by default) but you can turn off with hover = FALSE. It's in this branch which contains other updates waiting to be fully tested. You can give a try with devtools::install_github("bokeh/rbokeh@dev"). Let me know if this has the functionality that you expect.

cddesja commented 8 years ago

I would say almost. I know this isn't reproducible but ...

figure(logo = NULL) %>%
  ly_bar(Type, Percent, color = colors, data = tot.tab, alpha = 1, fill_color = colors, line_color = colors) %>% 
  x_axis(label = "") %>%
  theme_axis("x", major_label_orientation = 90)

Would it be possible to change the word "District", which is coming from the "Type" variable, to what the grouping variable is? For example, my grouping variable is actually a level of Age, which I've assigned some hex colors (in colors) to get a more friendly color scheme (using the viridis package).

Unrelated, is there a way to manually create a legend beyond setting the legend = "something" argument? For example, I would love to use the Age variable in this data set to assign create a legend? Sorry if this is off-topic. Thanks for the quick response btw.

screen shot 2016-08-24 at 2 01 23 pm
igoldin2u commented 8 years ago

I think it's important to have the hover argument to ly_bar to work similarly to ly_points. This doesn't work right now:

a <- ggplot2::diamonds %>% count(cut)
figure(a) %>% ly_bar(cut, n, hover=list(cut))
# Error in if (hover) { : argument is not interpretable as logical

Neither does ly_bar(..., hover=list(cut, n)).

I don't love the hover turned on by default, because it's not a default for ly_points.

hafen commented 8 years ago

@cddesja good point on needing more info in the tooltip when there is a grouping variable. I have made it so that the grouping variable is also shown on the tooltip. If you re-install from bokeh/rbokeh@dev, this should work.

@igoldin2u in ly_bar, the data is transformed from what is specified as the data argument into what needs to be plotted for the bar chart. Because of this, there isn't a nice mapping of variables in the input data to the hover tool, which is based on the data being plotted (in the case of the bar chart this data is the dimensions of the rectangles that need to be drawn), making it difficult to think of a hover specification similar to that in ly_points. This is a higher-level function that takes input and translates that into a different set of glyphs to be drawn, whereas ly_points takes the data directly and plots it. So for higher-level functions, meant to do very specific things, I think it is fine for their hover capability to be well-defined and just toggle-able with TRUE/FALSE. To your point, I disabled hover by default in my latest push, but I'm open to other opinions here as well (for a higher-level function where the tooltip is pre-defined and doesn't need any custom input from the user, maybe it would be nice to have tooltips on by default...).

hafen commented 8 years ago

@cddesja for your color issue, currently unfortunately it isn't possible to make a custom legend (legends are a bit tricky), but in the push I just made I added some convenience functions for controlling overall color palettes. When you map a variable to an attribute like color, you get the legend automatically. So with what I've just added, you should be able to follow this example (just swap my vector of colors with the viridis colors, etc.) and be in good shape:

figure() %>%
  ly_bar(yield, variety, color = year,
    data = lattice::barley, position = "fill") %>%
  set_palette(discrete_color = pal_color(c("red", "blue")))
igoldin2u commented 8 years ago

I skimmed layer_bar.R. I think there's two use cases - one where layer_bar.R does need to do data aggregation, and one where the initial data are already aggregated.

In either use case, I could pass in a callback function that is also used in the aggregation. Rewriting using dplyr, what we have now is:

res <- ggplot2::diamonds %>% group_by(cut) %>% 
    summarise(n=n())

And what we want, for example, is:

res <- ggplot2::diamonds %>% group_by(cut) %>%
    summarise(n=n(), 
    # `hover` is a callback that creates the hover tool-tip string.
    hover=hover(price))

One problem with this idea is that it introduces the dependency on dplyr. Unfortunately, aggregate only passes the aggregation function the vector of values being aggregated.

An alternative suggestion is to just let the user perform the aggregation before calling ly_bar, and to create an extra column in the data input that contains a pre-computed hover string.