The right way to hang a man
Repetitions

All your elif share the same structure. You just need to ensure that the inserted pattern is always 3 wide and you can drop your offsets adjustments. The logical next step is to use a dictionary to store the pattern and the row for each attempt:

_GOWN_MODIFIER = {
    1: (' O ', 2),
    2: (' | ', 3),
    3: ('/| ', 3),
    4: ('/|\\', 3),
    5: ('/  ', 4),
    6: ('/ \\', 4),
}

def wrong_answer(gown, attempt=0):

    height, width = len(gown), len(gown[-1].strip())

    offset1 = int((-width+23)*0.5)+1
    offset3 = int(ceil(0.5*(width-7)))
    if not attempt:
        return gown

    try:
        pattern, row = _GOWN_MODIFIER[attempt]
    except KeyError:
        raise Exception("Ops! The number of attempts must be an integer from 0 to 6.")
    else:
        gown[row] = '{:&gt;{}s} {:&gt;{}s}'.format(pattern, offset1, '|', offset3)

    return gown


Calculus

You do not need ceil nor int to perform an integer division by 2. In Python 2, / is already the operator you need. You can also use // which is also the same operation. The advantage of the latter over the former is that the behaviour is the same in Python 3, whereas / will perform a decimal division in Python 3.

_GOWN_MODIFIER = {
    1: (' O ', 2),
    2: (' | ', 3),
    3: ('/| ', 3),
    4: ('/|\\', 3),
    5: ('/  ', 4),
    6: ('/ \\', 4),
}

def wrong_answer(gown, attempt=0):
    if not attempt:
        return gown

    height, width = len(gown), len(gown[-1].strip())
    offset1 = (23 - width) // 2 + 1
    offset3 = (width - 6) // 2

    try:
        pattern, row = _GOWN_MODIFIER[attempt]
    except KeyError:
        raise Exception("Ops! The number of attempts must be an integer from 0 to 6.")
    else:
        gown[row] = '{:&gt;{}s} {:&gt;{}s}'.format(pattern, offset1, '|', offset3)

    return gown

def create_gown(width, height):
    half_width = width // 2
    gown = []
    gown.append('{:&gt;{}s}'.format('_'*half_width, 10))
    gown.append('{:&gt;{}s} {:&gt;{}s}'.format(
        '|', 11 - half_width, '|', half_width-2))
    for i in range(height-3):
        gown.append('{:^{}s}'.format('|', 20))
    gown.append('{:^{}s}'.format('-'*width, 20))
    return gown


Creation vs modifications

You're aware that you can create sequences of repeating elements using seq(element) * count. You can use that to create your gown variable by repeating the pole and then modifying the top two rows and the last one; it should be more memory friendly as the space needed to store the list will be allocated in one go:

def create_gown(width, height):
    half_width = width // 2
    gown = ['{:^{}s}'.format('|', 20)] * height
    gown[0] = '{:&gt;{}s}'.format('_' * half_width, 10)
    gown[1] = '{:&gt;{}s} {:&gt;{}s}'.format(
        '|', 11 - half_width, '|', half_width-2)
    gown[-1] = '{:^{}s}'.format('-' * width, 20)
    return gown


On modifying in place and returning a value

and a bit about printing too

Your wrong_answer both modifies the gown in place and return the modified value. This is unnecessary as the caller still should hold a reference to the value (which was modified). When calling the code, you can have:

gown2 = wrong_answer(gown, attempt=3)


but

&gt;&gt;&gt; gown2 is gown
True


So there is really no point in duplicating references to the same object. Instead, what you can do is preprocess the printing job, so you don't really need the print_gown function:

def wrong_answer(gown, attempt=0):
    height, width = len(gown), len(gown[-1].strip())
    offset1 = (23 - width) // 2 + 1
    offset3 = (width - 6) // 2

    if attempt:
        try:
            pattern, row = _GOWN_MODIFIER[attempt]
        except KeyError:
            raise Exception("Ops! The number of attempts must be an integer from 0 to 6.")
        else:
            gown[row] = '{:&gt;{}s} {:&gt;{}s}'.format(pattern, offset1, '|', offset3)

    return '\n'.join(gown)


Usage:

print(wrong_answer(gown, attempt=3))


Exceptions

Raising a generic purpose Exception is bad practice, as it makes the except clauses trying to handle your code being able to catch more than they should. You should at least use a more generic exception (such as ValueError) or define your own:

class AlreadyHangedError(ValueError):
    pass

def wrong_answer(gown, attempt):
    ...
    raise AlreadyHangedError('...')
    ...


However, there is something odd in the way you use your wrong_answer: the caller is expected to call this function using increasing attempts. This is the job for a generator. By turning wrong_answer into a generator, you can call it to create a generator instance and then call next on this instance (or let a for loop do it for you) to get the next gown to print:

def wrong_answer(width, height):
    gown = create_gown(width, height)
    offset1 = (23 - width) // 2 + 1
    offset3 = (width - 6) // 2

    yield '\n'.join(gown)
    for attempt in range(1, 7):
        pattern, row = _GOWN_MODIFIER[attempt]
        gown[row] = '{:&gt;{}s} {:&gt;{}s}'.format(pattern, offset1, '|', offset3)
        yield '\n'.join(gown)


Usage:

for gown in wrong_answer(10, 7):
    print(gown)


or, in a more real-case scenario:

def hangman_game():
    for gown in wrong_answer(10, 7):
        while True:
            status = manage_user_input()
            if status == 'FAILED':  # Whatever
                break
            if status == 'COMPLETED':  # Whatever
                return
        print gown
    print 'You lose'


Magic numbers

create_gown seems to center the gown in 20-sized strings, but what if width is greater than that? At first, you should define this value and give it a meaningful name, and same for all values that derive from it; and then, you might want to take max(20, width) as a base for your calculus.