Okay, I spent several hours testing this. The answer is...disappointing.
It appears that units are placed according to the order that they entered your army. Their order in the city or hero screens do not matter. The only order that matters is the one you see when you right-click your hero -- for some reason the army there is displayed in insertion order.
The pattern is:
That's it, until you add ranged units. Ranged units will step back one space if possible, swapping with a melee unit if it's there or pushing a ranged unit to the side. Oh and 7 jumps to the middle for no apparent reason.
Also note, reinforcing a unit does not reset it's position. So I could add 1, 2, 3, then put extra units on the first one added and it would still retain it's #1 position.
Okay, now the evidence.
First, I placed my units in order, from 1 to 7 like so:
In battle, I got the following pattern:
Simple enough, I thought. Next, I tried removing a few units, and got one of two expected outcomes:
Apparently it ignored empty spots and treated
1 _ 3 _ 5 _ 7 like it was
1 2 3 4.
I tried this in different fights, to make sure it wasn't enemy-dependent, and it seemed stable.
Then I decided to try multiple unit types, and things got weird:
Wha? That made no sense at all. I stumbled around for a bit, thinking maybe it was doing it based on unit strength or something, then made an important discovery: the right-click hero popup showed units in a seemingly random order (not the order I saw in the city or hero screens).
To confirm that it was the insertion order, I took all the units out and added them at random positions but in order from 1 to 7. The city screen looked random, but the right-click popup was in order:
Battle showed the expected pattern:
Great. I tried reversing the order and counting down from 7 to 1 and got the expected pattern.
I had previously noted that ranged units tended to move to the back, and so excluded them to avoid confusing the issue. Now I added them back in, and saw reasonable move-to-back behavior:
5 and 7 just moved back one step, and apparently 1 and 6 flipped but that seemed reasonable.
Then I tried all crossbowmen:
...I don't know what happened here, maybe someone else can decipher it. It looks like 2, 3, 4, and 5 did what I expected (normal position, but moved to the back). 1 and 6 got shuffled around a little, but they're more or less where they should be. But I can't explain how 7 got to the middle.
I suspect that what's really going on here is a simple algorithm that goes through the units and tries to place them on the board in a pseudo-spiral pattern. Unfortunately, it grabs the units in the order they were inserted, not the order they appear on the screen. As a programmer, that feels like a bug, not something someone did intentionally.
Now I'm going to go actually play the game, and try to forget that I ever learned this, because shuffling units in and out of cities just to get them inserted in the correct order seems like madness. I hope this helps someone.