I have found instructions for creating a las file by opening an existing file, modifying it, then re-saving it.

This re-uses the headers from the original file.

But how do I create a new file from scratch without loading another in the first place? I cannot see any documentation on the required format for the file, points, or headers.

I only need the bare minimum: x,y,z position for each point.

Here is how I assumed it might work...

import numpy as np
import laspy
import laspy.header
import laspy.file

points = []

#x,y,z values

header = laspy.header.Header()
outFile = laspy.file.File("./output.las", mode = "w", header = header)
outFile.points = np.array(points)

This fails with:

-> outFile.points = np.array(points)

-> self._writer.set_points(new_points)

-> self.data_provider._pmap[:] = points[:]

ValueError: could not broadcast input array from shape (3,3) into shape (3)

Could anyone kindly point to some sample code or tips to get this working?


3 Answers 3


Rather than setting the entire points array in one go, try setting each dimension in turn:

import laspy

header = laspy.header.Header()
outfile = laspy.file.File("output.las", mode="w", header=header)
outfile.X = [1, 2, 3]
outfile.Y = [0, 0, 0]
outfile.Z = [10, 10, 11]
  • Thanks! To get this working in other tools, I seem to also require: header.file_sig = 'LASF' Aug 19, 2015 at 23:19
  • 1
    You're correct. I was using the latest version from Github, the file_sig bug was fixed in a post-1.2.5 commit: github.com/grantbrown/laspy/commit/… Aug 20, 2015 at 13:20

The latest version of laspy will generate default file_sig = 'LASF', version_major = 1, version_minor = 2 and data_format_id = 0. However, the header offset and scale have to be specified. The following code (modified adamp's code) can generate output.las which can be read and then displayed using CloudCompare and QT Reader (The QT Reader needs minimum 4 points).

import laspy
import numpy as np

hdr = laspy.header.Header()

outfile = laspy.file.File("output.las", mode="w", header=hdr)
allx = np.array([1.000, 2.000, 3.000, 3.000]) # Four Points
ally = np.array([0.000, 0.000, 0.000, 3.000])
allz = np.array([10.000, 10.000, 11.000, 11.000])

xmin = np.floor(np.min(allx))
ymin = np.floor(np.min(ally))
zmin = np.floor(np.min(allz))

outfile.header.offset = [xmin,ymin,zmin]
outfile.header.scale = [0.001,0.001,0.001]

outfile.x = allx
outfile.y = ally
outfile.z = allz

  • How do I know what offset and scale should be?
    – mavavilj
    Jan 7, 2020 at 12:40

Until I can get this working with laspy, I am successfully working around it using txt2las from LAStools...

cmd = str("wine ./bin/txt2las -o lidar.las -parse xyz -stdin -itxt")
cmd_parts = cmd.split(" ")

from subprocess import Popen, PIPE, STDOUT
p = Popen(cmd_parts, stdout=PIPE, stdin=PIPE, stderr=PIPE)
stdout_data = p.communicate(input='0,0,0\n1,2,3\n,4,5,6')[0]
  • Can you elaborate on this approach more? I'd like to be able to automatically batch process .xyz files to .las.
    – mavavilj
    Jan 7, 2020 at 12:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.