Using the iris dataset, I am going to find a way to get the legend in coplot when I define the color of point as variable variable, in this example (Species).
in other words, I want to see a legend to tell me which shape and color represent which Species?
following is the script
coplot(Sepal.Width~Sepal.Length|Petal.Width*Petal.Length, data = iris,
number=c(3,3),overlap=.5,col=as.numeric(iris$Species),
pch=as.numeric(iris$Species)+1)
this is the produced graph:
coplot(Sepal.Width~Sepal.Length|Petal.Width*Petal.Length, data = iris,
number=c(3,3),overlap=.5,col=as.numeric(iris$Species),
pch=as.numeric(iris$Species)+1)
legend("topright", pch = unique(as.numeric(iris$Species)+1),
col = unique(as.numeric(iris$Species)),
legend = unique(iris$Species))
You just have to adjust legend position to what fits better to your figure size.
Related
I am making a scatter plot of two variables and would like to colour the points by a factor variable. Here is some reproducible code:
data <- iris
plot(data$Sepal.Length, data$Sepal.Width, col=data$Species)
This is all well and good but how do I know what factor has been coloured what colour??
data<-iris
plot(data$Sepal.Length, data$Sepal.Width, col=data$Species)
legend(7,4.3,unique(data$Species),col=1:length(data$Species),pch=1)
should do it for you. But I prefer ggplot2 and would suggest that for better graphics in R.
The command palette tells you the colours and their order when col = somefactor. It can also be used to set the colours as well.
palette()
[1] "black" "red" "green3" "blue" "cyan" "magenta" "yellow" "gray"
In order to see that in your graph you could use a legend.
legend('topright', legend = levels(iris$Species), col = 1:3, cex = 0.8, pch = 1)
You'll notice that I only specified the new colours with 3 numbers. This will work like using a factor. I could have used the factor originally used to colour the points as well. This would make everything logically flow together... but I just wanted to show you can use a variety of things.
You could also be specific about the colours. Try ?rainbow for starters and go from there. You can specify your own or have R do it for you. As long as you use the same method for each you're OK.
Like Maiasaura, I prefer ggplot2. The transparent reference manual is one of the reasons.
However, this is one quick way to get it done.
require(ggplot2)
data(diamonds)
qplot(carat, price, data = diamonds, colour = color)
# example taken from Hadley's ggplot2 book
And cause someone famous said, plot related posts are not complete without the plot, here's the result:
Here's a couple of references:
qplot.R example,
note basically this uses the same diamond dataset I use, but crops the data before to get better performance.
http://ggplot2.org/book/
the manual: http://docs.ggplot2.org/current/
There are two ways that I know of to color plot points by factor and then also have a corresponding legend automatically generated. I'll give examples of both:
Using ggplot2 (generally easier)
Using R's built in plotting functionality in combination with the colorRampPallete function (trickier, but many people prefer/need R's built-in plotting facilities)
For both examples, I will use the ggplot2 diamonds dataset. We'll be using the numeric columns diamond$carat and diamond$price, and the factor/categorical column diamond$color. You can load the dataset with the following code if you have ggplot2 installed:
library(ggplot2)
data(diamonds)
Using ggplot2 and qplot
It's a one liner. Key item here is to give qplot the factor you want to color by as the color argument. qplot will make a legend for you by default.
qplot(
x = carat,
y = price,
data = diamonds,
color = diamonds$color # color by factor color (I know, confusing)
)
Your output should look like this:
Using R's built in plot functionality
Using R's built in plot functionality to get a plot colored by a factor and an associated legend is a 4-step process, and it's a little more technical than using ggplot2.
First, we will make a colorRampPallete function. colorRampPallete() returns a new function that will generate a list of colors. In the snippet below, calling color_pallet_function(5) would return a list of 5 colors on a scale from red to orange to blue:
color_pallete_function <- colorRampPalette(
colors = c("red", "orange", "blue"),
space = "Lab" # Option used when colors do not represent a quantitative scale
)
Second, we need to make a list of colors, with exactly one color per diamond color. This is the mapping we will use both to assign colors to individual plot points, and to create our legend.
num_colors <- nlevels(diamonds$color)
diamond_color_colors <- color_pallet_function(num_colors)
Third, we create our plot. This is done just like any other plot you've likely done, except we refer to the list of colors we made as our col argument. As long as we always use this same list, our mapping between colors and diamond$colors will be consistent across our R script.
plot(
x = diamonds$carat,
y = diamonds$price,
xlab = "Carat",
ylab = "Price",
pch = 20, # solid dots increase the readability of this data plot
col = diamond_color_colors[diamonds$color]
)
Fourth and finally, we add our legend so that someone reading our graph can clearly see the mapping between the plot point colors and the actual diamond colors.
legend(
x ="topleft",
legend = paste("Color", levels(diamonds$color)), # for readability of legend
col = diamond_color_colors,
pch = 19, # same as pch=20, just smaller
cex = .7 # scale the legend to look attractively sized
)
Your output should look like this:
Nifty, right?
The col argument in the plot function assign colors automatically to a vector of integers. If you convert iris$Species to numeric, notice you have a vector of 1,2 and 3s So you can apply this as:
plot(iris$Sepal.Length, iris$Sepal.Width, col=as.numeric(iris$Species))
Suppose you want red, blue and green instead of the default colors, then you can simply adjust it:
plot(iris$Sepal.Length, iris$Sepal.Width, col=c('red', 'blue', 'green')[as.numeric(iris$Species)])
You can probably see how to further modify the code above to get any unique combination of colors.
The lattice library is another good option. Here I've added a legend on the right side and jittered the points because some of them overlapped.
xyplot(Sepal.Width ~ Sepal.Length, group=Species, data=iris,
auto.key=list(space="right"),
jitter.x=TRUE, jitter.y=TRUE)
I use the very nice survey package to create plots of a stratified samples in R. There are different ways to create scatter-plots that represent sampling weights but I prefer the so called Bubble plots. Bubble plots are scatter-plots with circles whose area is proportional to the sampling weight.
I would like to know if I can fill the bubbles with a specified color. Setting color of the outline works as described below. However changing the type of symbol with the pch parameter fails (this would be the standard method for scatter-plots in R).
library("survey")
data(api)
dstrat<-svydesign(id=~1,strata=~stype, weights=~pw, data=apistrat, fpc=~fpc)
# create bubble plot
svyplot(api00~api99, design=dstrat,
basecol=function(df){c("goldenrod","tomato","sienna")[as.numeric(df$stype)]},
style="bubble",alpha=c(0,1))
# try to set fill with pch (fails without error message)
svyplot(api00~api99, design=dstrat,
basecol=function(df){c("goldenrod","tomato","sienna")[as.numeric(df$stype)]},
style="bubble",alpha=c(0,1),pch=15)
We can do the following:
getcol <- function(df) c("goldenrod","tomato","sienna")[as.numeric(df$stype)]
svyplot(api00 ~ api99,
design = dstrat,
basecol = getcol,
style = "bubble",
alpha = c(0,1),
pch = 21,
bg = getcol(dstrat$variables))
Some comments:
In base R's plot, when using pch = 21 you can set the outline colour with col and fill colour with bg.
Here, basecol is an svyplot-specific argument, which internally sets the outline colour col.
We can use the same function that we used for basecol to fill circles with the matching colour, by recognising that dstrat$variables is the data.frame that contains column stype.
I am using plot3d() from rgl to make 3D scatter plots, using three columns, of samples in a data frame. Furthermore, I am using a fourth column colorby from my data frame (where each sample takes values, say, 10, 11, 12 as factors/levels) to color the points in the plot.
When using plot() to make 2D plots, I first set palette(rainbow(3)) and then col = colorby within plot() followed by legend(). The plot, colors and legend work fine.
However, when I repeat the last part for plot3d(), the coloring mixes up and not the same colors are assigned to the same levels as they would be in plot(). Moreover, if I use legend3d("topright", legend = levels(colorby), col = rainbow(3)) to create a legend, it looks the same as the 2D legend, but the coloring is clearly wrong in the 3D plot.
Where am I going wrong?
This looks correct to me:
df <- data.frame(x=1:9, y=9:1, z=101:109, colorby=gl(3,3))
palette(rainbow(3))
plot(x~y, df, col = df$colorby)
library(rgl)
with(df, plot3d(x,y,z, col = colorby))
legend3d("topright", legend = levels(df$colorby), col = levels(df$colorby), pch=19)
How is it possible to change type/color etc. in plot() if data.frame() is not only numeric?
Example:
a<-data.frame(col1=1:3,col2=1:3)
plot(a,type="o",col="blue")
results in:
whereas
a<-data.frame(col1=c("a","b","c"),col2=1:3)
plot(a,type="o",col="blue")
results in:
Expanding upon #alexis_laz's comment, you could hack your way out of this by initializing an invisible boxplot and consequently plotting your data on it.
# set border argument of boxplot() to "white"
plot(a, border = "white")
# add points to your plot
points(a$col2 ~ a$col1, col = "blue", type= "o")
I have two data set, I need to plot them in same graph. Here is the two dataset.
The following is the code I used to plot the data. How to plot above data in same plot ? How to set the graph legend on the x-axis? I tried setting it but it didn't work I got some error.
m_bs = conpl$new(sample_data1$V1)
m_eq = conpl$new(sample_data2$V1)
est = estimate_xmin(m_bs, xmax=5e+5)
est_eq = estimate_xmin(m_eq, xmax=Inf)
m_bs$setXmin(est_bs)
m_eq$setXmin(est_eq)
plot(m_bs)
lines(m_bs)
d = plot(m_eq, draw =FALSE)
points(d$x, d$y, col=2)
lines(m_eq,col=2,lwd=2)
Kindly let me know thanks.
You code works find for me when I used simulated data. However, I think your problem is with your data. In particular, you need to set the xlim values in your plot command. Something like:
min_x = min(sample_data1$V1, sample_data1$V2)
max_x = max(sample_data1$V1, sample_data1$V2)
plot(m_bs, xlim=c(min_x, max_x))
Should do the trick. To add a legend, just use the legend function
legend("bottomleft", col=1:2, legend = c("BS", "EQ"), lty=1)