Trying to add some note at the bottom of R plot graph, to show what colour and line type has been used in the graph that represents for. Tried use mtext() function, but that only allow me to add text, not the line type. Any way to add those colour note?
Try this approach. Please next time follow the advice of #AllanCameron. There are plenty of people wanting to help you, but we need to analyse your data to discover the issue. Here I have used some dummy data similar to that showed in the plot. Next an approach for your issue. If you want a description of your data series you can add a legend. This can be done also using ggplot2 which is used in actual code:
library(ggplot2)
#Data
df <- data.frame(Year=2000:2009,
Positive=runif(10,0,1),
Negative=runif(10,-1,0),
Average=cumsum(seq(-0.5,1,length.out = 10)))
#Plot
ggplot(df,aes(x=factor(Year),y=Positive))+
geom_line(aes(y=Average,group=1,color='Average'),size=1)+
geom_bar(stat='identity',color='black',aes(fill='Positive'),show.legend = T)+
geom_bar(aes(y=Negative,fill='Negative'),stat='identity',color='black')+
scale_fill_manual("",values=c('red','blue','white'))+
scale_color_manual("",values = 'black')+
theme_bw()+
theme(legend.position = 'bottom',legend.key.height = unit(0.001,'mm'))+
xlab('Year')+labs(caption = 'Your Info')
Output:
You can play around key size to make it thinner.
Related
I have a question about facet_wrap() in ggplot2.
I am trying to make a graph that looks like this. I attach an example image 1.enter image description here
In image 1 it can be seen that there are two maps and each one has its legend and color scale. I would like to be able to do this with ggplot and the facet_wrap() function.
My problem is that because the data in the dataframe is very different, they have a lot of amplitude for each map, when plotting the scale it does not allow me to visualize it the way I want.
enter image description here
ggplot(dataframe,mapping=aes(x=lon,x=lat))+
geom_contour_fill((aes(z=hgt,fill=stat(level)))+
geom_contour(aes(z=hgt),color="black",size=0.2)+
scale_fill_distiller(palette = "YlOrBr",direction = 1,super=ScaleDiscretised)+
mi_mapa+
coord_quickmap(xlim = range(dataframe$lon),ylim=range(dataframe$lat),expand = FALSE)+
facet_wrap(~nombre_nivel,scales="free", ncol =2) +
labs(x="Longitud",y="Latitud",fill="altura",title = "campos")
my dataframe has a shape like this. Where the facets are determined by the level variable. In this case the dataframe has another variable which is temp instead of hgt, but it's just another name.
enter image description here
Thanks
I think I've faced the alike problem building the two parts of the single map with two different scales. I found the package grid useful.
library(grid)
grid.newpage()
print(myggplot, vp = specifiedviewport)
In my case I built the first p <- ggplot() than adjusted p2 <- p + ...
with printing the two ggplots (p and p2) in two viewports. You can newly construct p2 with individual scale and print it in the grid. You can find useful information
here.
I try to generate a plot on which every point stands for an event. Color, Size and faced_grid are used to give additional information available in a visual way. The graph is working in ggplot2 but it is often important to know the exact numbers so an interactive version is needed which enables to hover over the point and get the info. I tried to convert the plot into an interactive version with the function ggplotly from the plotly-package. The problem then is, that the legend not only display the different states of the used attributes, it contains every existent combination. In addition, it did not display info from geom_rect.
I found related/similar questions but they used the function plot_ly and not ggploty or did not provide an answer.
Following, the same problem illustrated with the mtcars dataset:
library(plotly)
g = ggplot(mtcars,aes(x=mpg,y=disp,color = as.factor(cyl),size =as.factor(gear))) +
geom_point() +
geom_text(label = c(rep("A",nrow(mtcars)-5),rep("B",5)),color = "black",size=4) +
geom_rect(data=data.frame(name="zone",Start=20,End = 30,ymin = -Inf,ymax = Inf),aes(xmin=Start, xmax=End, ymin=ymin, ymax=ymax,fill=name),inherit.aes = FALSE,alpha=0.3)+
facet_grid(vs~am)
g
This is the result and how it should look like: ggplot Graph
Now using ggplotly
ggplotly(g)
This is the result: ggploty Graph
(1) The legend is now a combination of the different attributes used for Color and Size
(2) geom_rect is in the legend but didn’t get displayed in the graph
Does anyone knows how to get the same graph in ggplotly like in ggplot2? I am grateful for every hint. Thanks
Dave
I do not know how to fix the combination of legends when you use ggplotly. But, I can fix the second problem, if you do not use the Inf and -Inf, the geom_rect will work:
ggplotly(ggplot(mtcars,aes(x=mpg,y=disp, = as.factor(cyl),size =as.factor(gear))) +
geom_rect(aes( xmin=20,
xmax=30,
ymin=0,
ymax=max(mtcars$disp),
fill="Name"),
inherit.aes = FALSE, alpha=0.3) +
geom_point() +
geom_text(label = c(rep("A",nrow(mtcars)-5),rep("B",5)), = "black",size=4) +
facet_grid(vs~am))
However, the legends are bad.
I would suggest using subplot to create the same thing in Plotly, and I think this link Ben mentioned will help you create each subplot. One thing to mention is that I had trouble Illustrating different size in legend in plotly, while the size of the marker will be different, there will not be a legend for the size scale. Maybe a scale will be a better option.
Problem description
I'm writing a function that outputs a line plot ggplot2 object. I would like to have an argument that can control whether to add labels at the end of each line. A visual example is found here. The difficulty lies in the variable length of line labels. Ideally, the function will be smart enough to figure out the proper extra space to expand for the labels on the right.
In base R, there is a function graphics::strwidth that computes how many inches needed for the passed in string. I was wondering if there is a way that can do one step further, i.e. maps the string length to that with respect to the data scale. A dummy example is provided below for better explanation.
A dummy example
library(directlabels)
library(reshape2)
library(ggplot2)
dts <- cbind(`my long group 1` = mdeaths, `my long group 2` = fdeaths, time = 1:length(mdeaths))
ddf <- melt(as.data.frame(dts), id = "time")
names(ddf) <- c("time", "group", "deaths")
plot_wo_label <- ggplot(ddf, aes(x = time, y = deaths, group = group)) + geom_line()
plot_with_label <- plot_wo_label + geom_dl(aes(label = group), method = list(dl.combine('last.points')))
Plot with line label
As we can see above, the long line labels ('my long group 1' and 'my long group 2') get truncated due to the margin space. An ad hoc solution is to use xlim to expand the right edge of x-axis by trial and error. But that certainly is not an option in my case.
I know there are posted solutions by turning off clipping (like here), however, I imagine that some of the lines may end early and having a label at the canvas edge far away from the line end may cause difficulty to associate the labels with its corresponding lines.
So if there is a way to figure out how much space a string of arbitrary length will occupy on the x-axis (in the dummy example, the "duration" of label "my long group 1" in the "time" axis), that would be very helpful. But this is just one possible direction in my mind, other solutions are welcome and greatly appreciated!
Thanks!
The difficulty is that the absolute sizes of the text labels stay the same when you change the rendered output size of the plot. As a result, when you make the rendered size of the plot larger, the text labels span a smaller fraction of the plot area, and vice versa.
There's probably a way to generate the plot, dig into the grob structure of the plot to get the label width in plot coordinates, and then use scale_x_continuous to adjust the plot's x limits to include all of the label text. Unfortunately, I'm not sure how to do that, but hopefully someone else will come along who does.
For now, here's a demonstration of the issue. (I've switched to geom_text to place the labels, as I don't think directlabels is necessary here.):
library(tidyverse)
ggplot(ddf, aes(x = time, y = deaths, group = group)) +
geom_line() +
geom_text(data=ddf %>% group_by(group) %>% filter(time==max(time)),
aes(label=group), hjust=0, position=position_nudge(x=0.5)) +
scale_x_continuous(limits=c(0,1.15*max(ddf$time)))
Here's a screenshot of two saved versions of the plot, one version saved as a 700x350 pixel png file and the other saved as a 500x250 pixel png file. You can see that the absolute font sizes are the same, even though the sizes of the plots are different.
There are lots of situations where I use ggplot to create a nice looking graph, but I would like to play around with the colors/shapes/sizes for data belonging to a certain group (e.g. to highlight it).
I understand how to set these properties differently for each group when I first create the plot. However, I would like to know if there is a simple command to change the properties after the plot has been created preferably without having to specify the properties for all other subsets).
As an example consider the following code:
library(ggplot2)
x = seq(0,1,0.2)
y = seq(0,1,0.2)
types = c("a","a","a","b","b","c")
df = data.frame(x,y,types)
table_of_colors = c("a"="red","b"="blue","c"="green")
table_of_shapes = c("a"=15,"b"=15,"c"=16)
my_plot = ggplot(df) +
theme_bw() +
geom_point(aes(x=x,y=y,color=types,shape=types),size=10) +
scale_color_manual(values = table_of_colors) +
scale_shape_manual(values=table_of_shapes)
which produces the following plot:
I'm wondering:
Is there a way to change the color of the green point (type=="c") without having to type out the colors for the other points?
Is there a way to change the shape of the blue/red points (type %in% c("a","b")) without having to type out the shapes for all the other points?
The size of all points is currently set to 10. Is there a way to change the size of only the green point to say 15, while keeping the size of all remaining points at 10?
I'm not sure if this is an existing feature, but hacks are welcome (so long as the changes will be reflected in the legend).
This seems kind of hacky to me, but the code below addresses items 1 and 2 in your list:
my_plot +
scale_colour_manual(values=c(table_of_colors[1:2],c="green")) +
scale_shape_manual(values=c(a=4,b=6, table_of_shapes[3]))
I thought maybe you could change the size with something like scale_size_manual(values=c(10,10,15)), but that doesn't work, perhaps because size was hard-coded, rather than set with an aesthetic to begin with.
It would probably be cleaner to just create new vectors of shapes, colors, etc., as needed, rather than to make individual ad hoc changes like those above.
Using the likert package of R (more information: http://jason.bryer.org/likert/) to create these graphs which uses ggplot2.
Here is some example code to generate a graph using likert in R.
require(likert)
data(pisaitems)
items28 <- pisaitems[, substr(names(pisaitems), 1, 5) == "ST24Q"]
l28 <- likert(items28)
plot(l28)
Here is an example of what I want the output to show instead:
Firstly, I was wanting to add percentages into each box in the likert scale to represent the amount, instead of just in the middle like it currently offers. I have looked through the source code on github and can't understand how he does this.
Secondly, I was wondering it it were possible to have a subheading over each side of the middle divide to say "percentage of very low/low" and "percentage of high/very high" over on top of the graph which stays in relation to the rest of the plot.
Thanks
To add the percentages you just need to set the argument plot.percents to TRUE. I don't know a good solution for the subheading, but you can play around with the ggtitle and theme functions of the ggplot2 package. Here is one idea:
plot(l28, plot.percents = TRUE) +
ggtitle("Percentage of Strongly disagree/Disagree Percentage of Strongly agree/Agree") +
theme(plot.title = element_text(hjust = 0.45, size = 10))