Reputation: 170
I'm attempting to plot spectral response of training area pixels for a specific landcover. I have a dataframe that includes a reflectance value for each of 7 bands (columns) and and ID for each specific pixel. I would like each ID (pixel) to have a separate line and would like to be able to use the band number as the x axis.
My dataframe looks like this:
Class B1 B2 B3 B4 B5 B6 B7 ID
2 12345 13456 678 13456 7685 9870 12345 1
2 12345 1356 678 1456 7685 970 1235 2 ........
structure(list(B1 = c(12438, 12649, 12405, 12371, 13085, 12822
), B2 = c(11678, 11902, 11648, 11621, 12365, 12270), B3 = c(10982,
11467, 10961, 11021, 11478, 12159), B4 = c(10834, 11373, 10767,
10910, 10794, 12403), B5 = c(14453, 14079, 11810, 12060, 10403,
14923), B6 = c(13200, 14484, 11431, 12633, 8882, 16210), B7 = c(11414,
12318, 10370, 10641, 8020, 14293), class = structure(c(1L, 1L,
1L, 1L, 1L, 1L), .Label = c("2", "5", "9", "10", "12", "15",
"18", "20", "21"), class = "factor"), ID = 1:6), row.names = c(NA,
6L), class = "data.frame")
I would ideally like to be able to filter this on class (9 in all) and plot individual classes or more than one class to check out overlap between classes
I tried using melt to unpivot the dataframe and was somewhat successful but I had to summarize the spectral values by class. It also didn't like my x axis values as they are discrete so it wouldn't connect the lines. I fixed this by adding an integer column to the dataframe for each of the bands 1-7.
For this plot I would like to show each individual pixel (row) as a separate line (not summaries) on the plot to see if I selected pixels that are grouped together across all 7 bands. The bands would be across the x axis from B1 - B7
Is there a limit to the number of individual series you can put on one plot in ggplot? Is there an easier way to plot this dataframe as it is without having to use melt?
update..
I used melt and added an integer value to the melted dataframe so that I could use a continuous value for the x axis 1:7 to correspond with the band numbers. Here's the head of the melted dataframe. It still looks like it can't handle separate lines and wants me to summarize the values.
structure(list(ID = 1:6, variable = structure(c(1L, 1L, 1L, 1L,
1L, 1L), .Label = c("B1", "B2", "B3", "B4", "B5", "B6", "B7"), class =
"factor"),
value = c(12438, 12649, 12405, 12371, 13085, 12822), band = c(1,
1, 1, 1, 1, 1)), row.names = c(NA, 6L), class = "data.frame")
Upvotes: 0
Views: 80
Reputation: 66490
Here's an example using your top data. ggplot2
is really oriented to be easier if your data is long / tidy / melted, so I would recommend that in almost all cases.
library(tidyverse)
structure(list(B1 = c(12438, 12649, 12405, 12371, 13085, 12822),
B2 = c(11678, 11902, 11648, 11621, 12365, 12270),
B3 = c(10982, 11467, 10961, 11021, 11478, 12159),
B4 = c(10834, 11373, 10767, 10910, 10794, 12403),
B5 = c(14453, 14079, 11810, 12060, 10403, 14923),
B6 = c(13200, 14484, 11431, 12633, 8882, 16210),
B7 = c(11414, 12318, 10370, 10641, 8020, 14293),
class = structure(c(1L, 1L, 1L, 1L, 1L, 1L),
.Label = c("2", "5", "9", "10", "12", "15", "18",
"20", "21"), class = "factor"),
ID = 1:6), row.names = c(NA, 6L), class = "data.frame") %>%
# keep class and ID, but combine other columns into a
# key/value pair
gather(col, val, -c(class, ID)) %>% # from `tidyr`
ggplot(aes(col, val, color = ID, group = ID)) +
geom_line() +
facet_wrap(~class)
Upvotes: 1