[r] Plot multiple lines (data series) each with unique color in R

I am fairly new to R and I have the following queries :

I am trying to generate a plot in R which has multiple lines (data series). Each of these lines is a category and I want it to have a unique color.

Currently my code is setup in this way :

First, I am creating an empty plot :

plot(1,type='n',xlim=c(1,10),ylim=c(0,max_y),xlab='ID', ylab='Frequency')

Then for each of my category, I am plotting lines in this empty plot using a "for" loop like so :

for (category in categories){
lines(data.frame.for.this.category, type='o', col=sample(rainbow(10)), lwd=2)
}

There are 8 categories here, and so there are 8 lines produced in the plot. As you can see, I am trying to sample a color from the rainbows() function to generate a color for each line.

However, when the plot is generated, I find that there are multiple lines which have the same color. For instance, 3 of those 8 lines have green color.

How do I make each of these 8 lines have a unique color ?

Also, how do I reflect this uniqueness in the legend of the plot ? I was trying to lookup the legend() function, however it was not clear which parameter I should use to reflect this unique color for each category ?

Any help or suggestions would be much appreciated.

This question is related to r colors plot unique lines

The answer is


More than one line can be drawn on the same chart by using the lines()function

# Create the data for the chart.
v <- c(7,12,28,3,41)
t <- c(14,7,6,19,3)

# Give the chart file a name.
png(file = "line_chart_2_lines.jpg")

# Plot the bar chart.
plot(v,type = "o",col = "red", xlab = "Month", ylab = "Rain fall", 
   main = "Rain fall chart")

lines(t, type = "o", col = "blue")

# Save the file.
dev.off()

OUTPUT enter image description here


Using @Arun dummy data :) here a lattice solution :

xyplot(val~x,type=c('l','p'),groups= variable,data=df,auto.key=T)

enter image description here


Here is a sample code that includes a legend if that is of interest.

# First create an empty plot.
plot(1, type = 'n', xlim = c(xminp, xmaxp), ylim = c(0, 1), 
     xlab = "log transformed coverage", ylab = "frequency")

# Create a list of 22 colors to use for the lines.
cl <- rainbow(22)

# Now fill plot with the log transformed coverage data from the
# files one by one.
for(i in 1:length(data)) {
    lines(density(log(data[[i]]$coverage)), col = cl[i])
    plotcol[i] <- cl[i]
}
legend("topright", legend = c(list.files()), col = plotcol, lwd = 1,
       cex = 0.5)

You have the right general strategy for doing this using base graphics, but as was pointed out you're essentially telling R to pick a random color from a set of 10 for each line. Given that, it's not surprising that you will occasionally get two lines with the same color. Here's an example using base graphics:

plot(0,0,xlim = c(-10,10),ylim = c(-10,10),type = "n")

cl <- rainbow(5)

for (i in 1:5){
    lines(-10:10,runif(21,-10,10),col = cl[i],type = 'b')
}

enter image description here

Note the use of type = "n" to suppress all plotting in the original call to set up the window, and the indexing of cl inside the for loop.


If you would like a ggplot2 solution, you can do this if you can shape your data to this format (see example below)

# dummy data
set.seed(45)
df <- data.frame(x=rep(1:5, 9), val=sample(1:100, 45), 
                   variable=rep(paste0("category", 1:9), each=5))
# plot
ggplot(data = df, aes(x=x, y=val)) + geom_line(aes(colour=variable))

ggplot2_geom_line


If your data is in wide format matplot is made for this and often forgotten about:

 dat <- matrix(runif(40,1,20),ncol=4) # make data
 matplot(dat, type = c("b"),pch=1,col = 1:4) #plot
 legend("topleft", legend = 1:4, col=1:4, pch=1) # optional legend

There is also the added bonus for those unfamiliar with things like ggplot that most of the plotting paramters such as pch etc. are the same using matplot() as plot(). enter image description here


Here is another way to add lines using plot():

First, use function par(new=T)

option:

http://cran.r-project.org/doc/contrib/Lemon-kickstart/kr_addat.html

To color them differently you will need col().

To avoid superfluous axes descriptions use xaxt="n" and yaxt="n" for second and further plots.


In case the x-axis is a factor / discrete variable, and one would like to keep the order of the variable (different values corresponding to different groups) to visualise the group effect. The following code wold do:

library(ggplot2)
set.seed(45)

# dummy data
df <- data.frame(x=rep(letters[1:5], 9), val=sample(1:100, 45), 
                   variable=rep(paste0("category", 1:9), each=5))

# This ensures that x-axis (which is a factor variable)  will be ordered appropriately
df$x <- ordered(df$x, levels=letters[1:5])

ggplot(data = df, aes(x=x, y=val, group=variable, color=variable)) + geom_line() + geom_point() + ggtitle("Multiple lines with unique color")

enter image description here Also note that: adding group=variable remove the warning information: "geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?"


In addition to @joran's answer using the base plot function with a for loop, you can also use base plot with lapply:

plot(0,0,xlim = c(-10,10),ylim = c(-10,10),type = "n")

cl <- rainbow(5)

invisible(lapply(1:5, function(i) lines(-10:10,runif(21,-10,10),col = cl[i],type = 'b')))
  • Here, the invisible function simply serves to prevent lapply from producing a list output in your console (since all we want is the recursion provided by the function, not a list).

enter image description here

As you can see, it produces the exact same result as using the for loop approach.

So why use lapply?

Though lapply has been shown to perform faster/better than for in R (e.g., see here; though see here for an instance where it's not), in this case it performs roughly about the same:

Upping the number of lines to 50000 for both the lapply and for approaches took my system 46.3 and 46.55 seconds, respectively.

  • So, although lapply was just slightly faster, it was negligibly so. This speed difference might come in handy with larger/more complex graphing, but let's be honest, 50000 lines is probably a pretty good ceiling...

So the answer to "why lapply?": it's simply an alternative approach that works equally as well. :)


I know, its old a post to answer but like I came across searching for the same post, someone else might turn here as well

By adding : colour in ggplot function , I could achieve the lines with different colors related to the group present in the plot.

ggplot(data=Set6, aes(x=Semana, y=Net_Sales_in_pesos, group = Agencia_ID, colour = as.factor(Agencia_ID)))    

and

geom_line() 

Line Graph with Multiple colors


Examples related to r

How to get AIC from Conway–Maxwell-Poisson regression via COM-poisson package in R? R : how to simply repeat a command? session not created: This version of ChromeDriver only supports Chrome version 74 error with ChromeDriver Chrome using Selenium How to show code but hide output in RMarkdown? remove kernel on jupyter notebook Function to calculate R2 (R-squared) in R Center Plot title in ggplot2 R ggplot2: stat_count() must not be used with a y aesthetic error in Bar graph R multiple conditions in if statement What does "The following object is masked from 'package:xxx'" mean?

Examples related to colors

is it possible to add colors to python output? How do I use hexadecimal color strings in Flutter? How do I change the font color in an html table? How do I print colored output with Python 3? Change bar plot colour in geom_bar with ggplot2 in r How can I color a UIImage in Swift? How to change text color and console color in code::blocks? Android lollipop change navigation bar color How to change status bar color to match app in Lollipop? [Android] How to change color of the back arrow in the new material theme?

Examples related to plot

Fine control over the font size in Seaborn plots for academic papers Why do many examples use `fig, ax = plt.subplots()` in Matplotlib/pyplot/python Modify the legend of pandas bar plot Format y axis as percent Simple line plots using seaborn Plot bar graph from Pandas DataFrame Plotting multiple lines, in different colors, with pandas dataframe Plotting in a non-blocking way with Matplotlib What does the error "arguments imply differing number of rows: x, y" mean? matplotlib get ylim values

Examples related to unique

Count unique values with pandas per groups Find the unique values in a column and then sort them How can I check if the array of objects have duplicate property values? Firebase: how to generate a unique numeric ID for key? pandas unique values multiple columns Select unique values with 'select' function in 'dplyr' library Generate 'n' unique random numbers within a range SQL - select distinct only on one column Can I use VARCHAR as the PRIMARY KEY? Count unique values in a column in Excel

Examples related to lines

Plot multiple lines (data series) each with unique color in R More than 1 row in <Input type="textarea" /> Skip first couple of lines while reading lines in Python file remove empty lines from text file with PowerShell Find duplicate lines in a file and count how many time each line was duplicated? Batch / Find And Edit Lines in TXT file count (non-blank) lines-of-code in bash