Landscape Ecology

Jeffery B. Cannon


This collection of training modules is designed to get you started with basic LiDAR analysis for natural resources and forest ecology using R. It is primarily meant to help my students and staff get oriented to LiDAR analyses. By sharing it online, I am hoping others find it useful. These modules assume that you have a basic understanding of the R programming language, and some experience installing packages, manipulating data, and writing basic functions. By the time you finish this module you should be able to:

Module 1: Acquiring, loading, and viewing LiDAR data

Introduction and goals

Before getting started with LiDAR analyes, it is useful to know about different sources of LiDAR data, as well as how to load and view it in R. By the time you finish this module you should be able to:

Downloading R packages

You will need several packages to get started. Some are mandatory, others are optional. The basic packages are available through the CRAN repository. However, because LiDAR technology is rapidly developing, some must be downloaded using their development version through GitHub.

# install CRAN packages if you haven't already

# source the SDL package and then install lidRviewer from Github


# load the libraries


LiDAR data sources

  1. Download this sample LiDAR dataset to get start practicing right away with no fuss. This data will form the basis of the first four modules of this tutorial. I have learned some users with lower RAM resources have issues with the 150 MB dataset. You can also downloaded this reduced LiDAR dataset instead.
  2. The USGS 3D Elevation Program (3DEP) provides LiDAR data coverage for large portions of the continental US, Puerto Rico, and the US Virgin Islands. Coverage is lower for Alaska and Hawaii. LidDAR acquisitions for the state of Georgia were completed over the years of 2019-2021 by USGS 3DEP.
  3. For ecological research, you will find repeated LiDAR acquisitions at select sites of the National Ecological Observatory Network (NEON). LiDAR data from NEON is available between 2018 to present–approximately annually–at dozens of sites in the network. The sample data we are using comes from a section of the 2023 dataset from the JERC (Jones Center at Ichauway) longleaf pine ecosysetem in Newton, Georgia. We will return to this entire dataset in Module 5: Speeding up your analyses: Reduced datasets .

Sample LiDAR dataset from longleaf pine woodland in southwest Georgia as shown in the OpenSource software CloudCompare.

Publicly available LiDAR data available via USGS 3D Elevation Program.

Loading LiDAR data into R

Loading and viewing data in R is made simple with built-in functions in the lidR package. The typically large size of LiDAR data can create challenges for viewing them. You can use the lidRviewer package to view LiDAR data. An unfortunate downside is that it halts other R operations while you are viewing. Another option is to subset the data which we will cover in Module 5: Speeding up your analyses: Reduced datasets. You can also view point clouds in the specialized OpenSource Software Cloud Compare.

LiDAR data comes as a *.las file type which is uncompressed or *.laz which is a compressed version. You will also see *.lax files. These are index files which can greatly speed up your processing. We will cover indexing in Module 5: Speeding up your analyses: Reduced datasets. Less commonly you may also encounter raw point clouds in text formats (e.g., *.txt or *.xyz).


# Load example dataset above, or path to your data.
las = readLAS('NEON_D03_JERC_DP1_740000_3459000_classified_point_cloud.laz')

# or if you donwloaded the reduced dataset instead
# las = readLAS('NEON_D03_JERC_DP1_740000_3459000_classified_point_cloud-reduced.laz')

# plot using native RGL viewer. Note this may take a few seconds

# plot using the
lidRviewer package. Quick but more limited
# also a little buggy

# MacOS users leave off the backend='lidRviewer' part if you were unable to install the package

plot(las, backend = 'lidRviewer')

You will notice that there is some noise in the dataset. There are some extraneous points that occur very high above or below the scene. This stretches the color gradient and makes it hard to see any detail. Some noise is inevitable due to reflections, smoke and particulates, or even birds. You will need to filter these out.

The lidR package has functions to help filter out noise. It searches for returns that are far from neighbors ivf() the isolated voxel filter. Here, we filter all points where there is no more than n = 3 return within a resolution of 1 m. We then filter out the points of interest that are not classifid as noise. Note the variable LASNOISE = 18.

# Classify all isolated returns. Takes a few seconds
las = classify_noise(las, ivf(res = 3, n = 10))

# The classify_noise function sets Classification = 18 (LASNOISE = 18)
las = filter_poi(las, Classification != LASNOISE)
plot(las, backend = 'lidRviewer')

# This still has some pesky noise that must be in a cluster. Let's delete it.
# Take a look at the highest point, and filter out data below it

# The highest point value has a Z of 972.81. Keep only points below it.
las = filter_poi(las, Z < 970)

# View it now
plot(las, backend = 'lidRviewer')

# MacOS users leave off the backend='lidRviewer' part if you were unable to install the package

Sample data showing results of noise and height filter

You saw in the last section that the las object had the attribute Z corresponding in this case to elevation. There are many other attributes we can also see. Check the las@data slot to see what all the column names are. You can color point clouds by some of these traits (including RGB color values). Here are some useful ones to know.


# The Z attribute is the default, so we've already seen this
plot(las, color='Z', backend='lidRviewer')

# YOu can view the wavy strips when viewing based on the timestamp of the return
plot(las, color='gpstime', backend='lidRviewer')

# Ground and trunks have a higher intensity than vegetation
plot(las, color='Intensity', backend='lidRviewer')

# This point cloud is already classified. We'll learn to classify points later
# Green = tall vegetation, yellow = short vegetation, blue = ground
plot(las, color='Classification', backend='lidRviewer')

# Color by RGB
plot(las, color='RGB') # This uses the rgl viewer and may be slow. It's possible to get this to work in lidRviewer, but I didn't get it to work.

Sample plot illustrating coloring by various attributes associated with the lidar data.

Next steps

Now you can download, de-noise, and view basic LiDAR data. Now that we have the basics., we will start extracting useful information from the point clouds. In the next module, you will learn how to

Continue learning