How would one go about plotting multiple density plots on the same set of axes? I understand how to plot multiple line graphs and scatter plots together, however the matter of having the density plots share a common x-axis is tripping me up. My data is currently set up as such:
name x1 x2 x3
a 123 123 123
b 123 123 123
c 123 123 123
Thanks for the help!
EDIT: Here are some details I was missing which may help make my question clearer.
I have a data frame attr_gains which looks like the example above, and whose variable names are Str, Agi, and Int. So far, I have been able to get a density plot of the Str variable alone with this code:
attr_gains %>%
ggvis(x=~Str)%>%
layer_densities(fill :="red", stroke := "red")
What I would like to do is overlay two more density plots, one for Agi and Int each, so that I have three density plots on the same set of axes.
Directly from the documentation:
PlantGrowth %>%
ggvis(~weight, fill = ~group) %>%
group_by(group) %>%
layer_densities()
Link
Your Case:
set.seed(1000)
library('ggvis')
library('reshape2')
#############################################
df = data.frame(matrix(nrow = 3, ncol = 5))
colnames(df) <- c('names', 'x1', 'x2', 'x3', 'colors')
df['names'] <- c('a','b','c')
df['x1'] <- runif(3, 100.0, 150.0)
df['x2'] <- runif(3, 100.0, 150.0)
df['x3'] <- runif(3, 100.0, 150.0)
df['colors'] <- c("blue","orange","green")
df <- melt(df)
#############################################
df %>%
ggvis( ~value, fill = ~colors ) %>%
group_by(names) %>%
layer_densities()
Please see this SE page for information on controlling ggvis color(s).
Looks like this:
Related
I'm using ggplot to create a scatterplot of a dataframe. The x and y axis are two columns in the frame, and the following code gives me a scatter plot:
ggplot(df,aes(x=Season,y=type))+
geom_point(fill="blue")
But the points are all the same size. I want each point to depend on the count of how many rows matched for the combination of x and y. Anyone know how?
You haven't provided any sample data, so I'm generating some:
library('tidyverse')
df <- data.frame(Season = sample(c('W', 'S'), size=20, replace=T),
type=sample(c('A', 'B'), size=20, replace=T))
df %>%
group_by(Season, type) %>%
summarise(count = n()) %>%
ggplot(aes(x=Season, y=type, size=count)) +
geom_point(col="blue")
The idea is to count all the occurences of your Season–type data, and then use that new count field to adjust the size in your ggplot.
I have a time series data frame similar to data created below. Measurements of 5 variables are taken on each individual. Individuals have unique ID numbers. Note that in this data set each individual is of the same length (each has 1000 observations), but in my real data set each individual is of has different lengths (teach individual has a different number of observations). For each individual, I want to plot all 5 variables on top of one another (i.e. all on the y axis) and plot them against time (x axis). I want to print each of these plots to an external document of some kind (pdf, or whatever is recommended for this application) with one plot per page, meaning each individual will have its own page with a single plot. I want these time series plots to be "interactive", in that I can move my mouse over a point, and it will tell me what time individual data points are at. My goal in doing this is exploring the association between peaks, valleys, and other regions between the 5 variables. I am not sure if ggplot2 is still the best application for this, but I would still like for the plots to be aesthetically appealing so that it will be easier to see patterns in the data. Also, is pasting these plots to a pdf the most sensible route? Or would I be better off using R notebook or some other application?
ID <- rep(c("A","B","C"), each=1000)
time <- rep(c(1:1000), times = 3)
one <- rnorm(1000)
two <- rnorm(1000)
three <- rnorm(1000)
four <- rnorm(1000)
five<-rnorm(1000)
data<- data.frame(cbind(ID,time,one,two,three,four,five))
Try using the plotly package. And since you want it to be interactive, you'll want to export as something like html rather than pdf.
To produce a single faceted plot (note I added stringAsFactors = FALSE to your sample data):
library(tidyverse)
library(plotly)
ID <- rep(c("A","B","C"), each=1000)
time <- rep(c(1:1000), times = 3)
one <- rnorm(1000)
two <- rnorm(1000)
three <- rnorm(1000)
four <- rnorm(1000)
five<-rnorm(1000)
data<- data.frame(cbind(ID,time,one,two,three,four,five),
stringsAsFactors = FALSE)
data_long <- data %>%
gather(variable,
value,
one:five) %>%
mutate(time = as.numeric(time),
value = as.numeric(value))
plot <- data_long %>%
ggplot(aes(x = time,
y = value,
color = variable)) +
geom_point() +
facet_wrap(~ID)
interactive_plot <- ggplotly(plot)
htmlwidgets::saveWidget(interactive_plot, "example.html")
If you want to produce and export an interactive plot for every ID programmatically:
walk(unique(data_long$ID),
~ htmlwidgets::saveWidget(ggplotly(data_long %>%
filter(ID == .x) %>%
ggplot(aes(x = time,
y = value,
color = variable)) +
geom_point() +
labs(title = paste(.x))),
paste("plot_for_ID_", .x, ".html", sep = "")))
Edit: I changed map() to walk() so that the plots are produced without console output (previously just a list with 3 empty elements).
There are times when we would like to know how the clustering of points might change through time. For example, say you have cities with demographic attributes by decade and you are interested in what cities are the "most similar" based on their attributes for each decade. Here is a toy dataset that illustrates the point:
set.seed(1)
centers <- data.frame(cluster=factor(1:3),
size=c(100, 150, 50),
x1=c(5, 0, -3),
x2=c(-1, 1, -2))
year1 <- centers %>%
group_by(cluster) %>%
do(data.frame(x1=rnorm(.$size[1], .$x1[1]),
x2=rnorm(.$size[1], .$x2[1]),
year="year 1",
stringsAsFactors = F)) %>%
data.frame()
year2 <- centers %>%
group_by(cluster) %>%
do(data.frame(x1=rnorm(.$size[1], .$x1[1]),
x2=rnorm(.$size[1], .$x2[1]),
year="year 2",
stringsAsFactors = F)) %>%
data.frame()
points <- rbind(year1,year2)
We can calculate kmeans per year using something like below:
kclusters <- points %>%
select(-cluster) %>%
group_by(year) %>%
do(data.frame(., kclust = kmeans(as.matrix(.[,-3]),centers=3)$cluster)) %>%
mutate(kclust = as.character(kclust))
And here is the resulting plot:
ggplot(kclusters) +
geom_point(aes(x1,x2,color=kclust)) +
facet_wrap(~year) +
theme_bw() +
scale_color_viridis_d()
The code works as expected but notice that the cluster IDs have changed. It doesn't make much difference here because I am plotting the clusters using the original x1 and x2, but my real example is making a map and the points are plotted in space using coordinates and colored according to clusters (i.e., the location of the point never changes). Imagine this same plot for several years--it becomes hard to track the changing cluster membership of individual points each year. Is there a way to keep the IDs consistent?
I want to be able to graph some points based on if one parameter is true in a data frame. I want to only use the position coordinates if in the "Time" column is equal to 2. How do I write this in R?
In the future it'd helpful to dput some data. The packages dplyr and ggplot2 are two popular packages you might want to look into.
library(dplyr)
library(ggplot2)
Create something that your data might look like:
df <- data.frame(x = runif(10), y = runif(10), Time = sample(1:2, 10, replace = T))
Filter then plot:
df_tmp <- df %>% filter(Time == 2)
ggplot(df_tmp, aes(x,y)) + geom_point()
My df is a database of individuals (rows) and amount they spent (column) in one activity. I want to draw a scatterplot in R that has the following characteristics:
x-axis: log(amount spent)
y-axis: log(number of people that spent this amount)
This is how far I got:
plot(log(df$Amount), log(df$???))
How can I do that? Thanks!
My df looks something like this:
df
Name Surname Amount
John Smith 223
Mary Osborne 127
Mark Bloke 45
This is what I have in mind (taken from a paper by Chen (2012))
Try this:
library(dplyr)
library(scales) # To let you make plotted points transparent
# Make some toy data that matches your df's structure
set.seed(1)
df <- data.frame(Name = rep(letters, 4), Surname = rep(LETTERS, 4), Amount = rnorm(4 * length(LETTERS), 200, 50))
# Use dplyr to get counts of loans in each 5-dollar bin, then merge those counts back
# into the original data frame to use as y values in plot to come.
dfsum <- df %>%
mutate(Bins=cut(Amount, breaks=seq(round(min(Amount), -1) - 5, round(max(Amount) + 5, -1), by=5))) # Per AkhilNair's comment
group_by(Bins) %>%
tally() %>%
merge(df, ., all=TRUE)
# Make the plot with the new df with the x-axis on a log scale
with(dfsum, plot(x = log(Amount), y = n, ylab="Number around this amount", pch=20, col = alpha("black", 0.5)))
Here's what that produced: