ggplotly created object does not dynamically adjust gridlines when zooming in - r

I'm trying to understand why plotly objects which are converted from ggplot2 objects using the ggplotly function do not dynamically rescale the grid when using plotly's zoom feature on the html widget.
I would like to find a solution to this without the need to recode all plots as native plotly objects.
Am I missing something, or could it be that this functionality is just not supported yet in the plotly package?
Here is some sample code illustrating the problem (before executing, you need to set the your.path variable to the directory you want the htmlwidget to be saved in):
library(ggplot2)
library(plotly)
library(htmlwidgets)
ggp <- ggplot(data=mtcars, aes(x=hp, y=mpg)) + geom_point() + theme_bw()
ply.ggp <- ggplotly(ggp)
saveWidget(ply.ggp, paste(your.path, "mtcarsGGPLOT.html", sep=""))
On this html widget when you zoom in, the grid scale remains static (e.g. the x grid lines on 100, 200, 300 are the only one you can see, even if you zoom in. There are no new grid lines visible e.g. at 25, 50, 75, etc.)
Compare this to the widget when creating the plot directly in plotly with this sample code:
ply <- plot_ly(data=mtcars, x=mtcars$hp, y=mtcars$mpg)
saveWidget(ply, paste(your.path, "mtcarsNATIVE.html", sep=""))
Here when you zoom in a region of the plot, a new dynamic grid is visible.
EDIT: Could it be that the observation occurs due to the htmlwidgets package rather than plotly or ggplot2. But then again, why would the native plotly graphic render correctly when using htmlwidgets while the ggplot converted one doesn't..?

I've also spent time trying to figure this out and it's actually quite simple.
Set dynamicTicks equal to TRUE within ggplotly.
ply.ggp <- ggplotly(ggp, dynamicTicks = TRUE)
I just tried creating the widget and it worked for me.

Related

Vertical vistime timeline and overlapping geom_text labels

I'm trying to draw a vertical timeline using vistime with its ggplot plotting option. My main intention is to better integrate it with text, side by side. This is the code:
library("vistime")
library("plotly")
data <- read.csv("../../data/programming.csv")
g <- gg_vistime(data, col.event="Item", col.start="Start.Date", col.end="End.Date", col.group="Group")
g + theme(axis.text.x = element_text(angle=90, color='blue4',size=14) )+coord_flip()
As you can see, as I'm doing the coord_flip, the labels intersect with each other. I'd like to make the labels go vertical. This is code that draws them:
https://github.com/shosaco/vistime/blob/372da36791cbdb7ad7d6841ed991e55b36f77e06/R/plot_ggplot.R#L83-L91
So that means that it's a geom_text sentence. Is there some way to change the orientation of geom_text-drawn text once it's done? Can I use some theme command to do that? Barring that, is there any way I can change the placement of the labels using vistime?
You can deconstruct any ggplot2 visualization with (surprisingly) ggplot_build (actually, what it does is to create elements that can be rendered using the plain vanilla plot).
data <- read.csv("data/programming.csv")
g <- gg_vistime(data, col.event="Item", col.start="Start.Date", col.end="End.Date", col.group="Group") + theme(axis.text.x = element_text(angle=90, color='blue4',size=14) )+coord_flip()
g.d <- ggplot_build(g)
g.d$data[[4]]$angle <- 90
rebuilt <- ggplot_gtable(g.d)
png(filename="img/timeline.png", width=240, height=960)
plot(rebuilt)
dev.off()
That creates a data frame with different elements of the plot, including g.d$data which contains, effectively, the data and its properties when rendered in its 4th element. g.d$data[[4]]$angle contains the angle of all the geom_text elements that have been rendered. So once you get that, it's just a matter of changing it individually or colectively to what you want. You need to reconstruct the plot using ggplot_gtable and then use the core plot command to plot and render it any way you want, in this case a png.
At any rate, ggplot_build allows you to introspect the data structures and different pieces of the graph created using ggplot, changing any one of its layers, metadata or pieces after they have been created. In our case, it produces the intended effect

ggplot with the same width and height as ggsave(width=x, height=y)

Within R-Studio, I am generating plots with ggplot, then I save them with ggsave() for further use (I know, not ideal, but non-optional right now).
My problem is that when I generate the plot before saving it, R shows it to me in a particular size. With ggsave, I set width and height, so the elements displayed shift etc. I only see this after saving the plot.
I want R to show it to me before. I thus assume that I need to set the size of the plot within ggplot() somewhere , not in ggsave().
How can I do this in the least complicated fashion?
library(ggplot2)
ggplot(mtcars, aes(mpg,disp)) + geom_point() +
labs(title="Rocket science title that will get cut by ggsave")
ggsave("rocketScience.png", width=10, height=7, unit="cm")
You can use the set_panel_size() function from the egg package.
With this function you can fix the panel size of the plot. This can be very useful when creating multiple plots that should have the exact same plotting area but use varying axis labels or something similar that would usually slightly change the panel dimensions. Especially useful for presentations with seamless animations or publications. It also ensures the same dimensions in the preview and the saved plot.
p <- ggplot(mtcars, aes(mpg,disp)) +
geom_point() +
labs(title="Rocket science title that will get cut by ggsave")
#to view the plot
gridExtra::grid.arrange(egg::set_panel_size(p=p, width=unit(5, "cm"), height=unit(7, "cm")))
#to save the plot
ggsave(filename = "myplot.pdf", plot = egg::set_panel_size(p=p, width=unit(5, "cm"), height=unit(7, "cm")))
Within ggsave you can still manipulate the size of the whole "page" saved, but this will only influence the amount of white space around the plot. The actual panel size will stay fixed.
The example plot from above with 5cm or 15cm as width:
I don't believe this is achievable via ggplot settings; you might get around it if using RMarkdown, as you can set with and height of an output of a markdown chunk via fig.width and fig.height params.

How to move the legend to outside the plotting area in Plots.jl (GR)?

I have the following plot where part of the data is being obscured by the legend:
using Plots; gr()
using StatPlots
groupedbar(rand(1:100,(10,10)),bar_position=:stack, label="item".*map(string,collect(1:10)))
I can see that using the "legend" attribute, the legend can be moved to various locations within the plotting area, for example:
groupedbar(rand(1:100,(10,10)),bar_position=:stack, label="item".*map(string,collect(1:10)),legend=:bottomright)
Is there any way of moving the plot legend completely outside the plotting area, for example to the right of the plot or below it? For these kinds of stacked bar plots there's really no good place for the legend inside the plot area. The only solution I've been able to come up with so far is to make some "fake" empty rows in the input data matrix to make space with some zeros, but that seems kind of hacky and will require some fiddling to get the right number of extra rows each time the plot is made:
groupedbar(vcat(rand(1:100,(10,10)),zeros(3,10)),bar_position=:stack, label="item".*map(string,collect(1:10)),legend=:bottomright)
I can see that at there was some kind of a solution proposed for pyplot, does anyone know of a similar solution for the GR backend? Another solution I could imagine - is there a way to save the legend itself to a different file so I can then put them back together in Inkscape?
This is now easily enabled with Plots.jl:
Example:
plot(rand(10), legend = :outertopleft)
Using layouts I can create a workaround making a fake plot with legend only.
using Plots
gr()
l = #layout [a{0.001h}; b c{0.13w}]
values = rand(1:100,(10,10))
p1 = groupedbar(values,bar_position=:stack, legend=:none)
p2 = groupedbar(values,bar_position=:stack, label="item".*map(string,collect(1:10)), grid=false, xlims=(20,3), showaxis=false)
p0=plot(title="Title",grid=false, showaxis=false)
plot(p0,p1,p2,layout=l)

Making pie chart's contours smoother on Shiny

I am trying to have a nice looking plot for two (or possibly more) continuous values in the form of a pie chart using ggplot2.
The code is the following :
library("ggplot2")
library("ggthemes") ## for theme_economist
df <- data.frame(origin=c('with','without'),value=c(24536,50456))
pie <- ggplot(df, aes(x = "",y=value, fill = origin))+
geom_bar(width = 1,stat="identity")+
coord_polar(theta = "y",start=pi/3)+
theme_economist()
The pie is relatively fine except that the contours of the pie seems to be a bit irregularly drawn.Of course when you export it as a pdf it looks fine but displayed in RStudio or Shiny it doesn't look nice at all.
Is there a way to change the resolution of the ggplot object directly or to make renderplot() aware that we want to display the image at a high resolution ?
I tried modifying the res argument of the renderPlot() function but it distorts the image and do not get rid of the irregularity of the border.
How to make the contours of the pie smoother on Shiny or RStudio directly ? Thanks.
To improve the resolution of the plot on Shiny you have to set the res argument to its default value of 72. It does not make a lot of sense to me but it worked just fine the resolution went from really bad to really nice !
However increasing its value further can lead to distortion of the image.
It seems that for now you cannot change the resolution of the plotting object itself before exporting it or rendering it into Shiny.

Hiding Data Point on qplot

I have downloaded the directlabels package in R to further enhance the ggplot2 experience, however I would like to delete the data point of a scatterplot once I have added the labels to them. Is there any way to hide these? My code goes something like this:
q<-qplot(x,y)+geom_point(aes(colour=z))
direct.label(q,list(cex=0.75,fontface="bold",bumpup))
But I'm not sure where the command to hide the data point would be. I would use first.qp but in this case I get the error
Error in order.labels(d) : labels are not aligned
so is there a better way of doing this?
You example is not reproducible. So I will just answer this question:
"I would like to delete the data point of a scatterplot once I
have added the labels to them."
You can easily for example remove a layer from the gg object. First I create a ggplot2 example and I decorate it using direct.label.
library(directlabels)
scatter <- qplot(jitter(hwy),jitter(cty),data=mpg,colour=class,
main="Fuel efficiency depends on car size")
scatter <- direct.label(scatter,list(cex=0.7,bumpup))
I remaove the first layer now(the geom_point layer)
scatter$layers[1] <- NULL
Then you get this plot , as you see I had only labels without points:
scatter

Resources