I did some work with the script provided. I didn't clarify at the beginning that I was creating the tiles individually at init, so I didn't have a large initial map. I set the min for panel to a default value. Then I added the XY loops for generating the tiles. Looked good. I then ported it to C#, which is what I'm working in. Thanks for the assist.

For future reference, here's my final GD script:
extends ScrollContainer
const TILE_SIZE = 64.0
var panel:Panel
var tile_map:TileMap
func _ready() -> void:
# Make a panel to give the scroll container a size.
panel = Panel.new()
add_child(panel)
tile_map = TileMap.new()
tile_map.tile_set = TileSet.new()
panel.add_child(tile_map)
# Set the panel size to the used area of the map.
panel.rect_min_size = Vector2(1000,500)
panel.rect_clip_content = true
var tex = load('res://Ground.png')
for y in 5:
for x in 20:
var id = tile_map.tile_set.get_last_unused_tile_id()
tile_map.tile_set.create_tile(id)
var name = "Tile"
tile_map.tile_set.tile_set_name(id, name)
tile_map.tile_set.tile_set_texture(id, tex)
tile_map.set_cell(x, y, id)
# Called every frame. 'delta' is the elapsed time since the previous frame.
#func _process(delta):
# pass