Elementos auxiliares (Polígonos)
O patch disponível para inserir polígonos é o Polygon. Este elemento requer apenas 1 parâmetro, que é o parâmetro xy, que recebe uma list de list, onde as lists internas devem conter as coordenadas xy para cada vértice do polígono (cada list interna deve conter dois elementos numéricos). O número de list internas irá determinar o número de vértices que o polígono terá.
Por exemplo, a list [[1,1]] irá desenhar apenas 1 vértice (apenas 1 ponto).
Já a list [[1,1], [2,2]] irá desenhar dois vértices ligados, o primeiro na coordenada xy=(1,1), e o segundo na coordenada xy=(2,2), formando uma reta.
Já a list [[1,1], [2,2], [3,1]] irá desenhar três vértices ligados, o primeiro na coordenada xy=(1,1), o segundo na coordenada xy=(2,2), e o terceiro na coordenada xy=(3,1), formando um triângulo.
Já a list [[1,1], [2,2], [3,1], [2, 0.7]] irá desenhar quatro vértices ligados, o primeiro na coordenada xy=(1,1), o segundo na coordenada xy=(2,2), o terceiro na coordenada xy=(3,1), e o quarto na coordenada xy=(2,0.7), formando uma figura geométrica de 4 lados.
Por exemplo, para desenhar um triângulo, é necessário passar três lists internas:
plt.figure(figsize=(8,6))
plt.scatter(x,y)
plt.gca().add_patch(patches.Polygon(xy=([[1,1], [2,2], [3,1]])))
plt.show()
Figura 1 - Gráfico de dispersão com um triângulo inserido.

Para desenhar um polígono de 4 lados, é necessário passar 4 lists internas:
plt.figure(figsize=(8,6))
plt.scatter(x,y)
plt.gca().add_patch(patches.Polygon(xy=([[1,1], [2,2], [3,1], [2, 0.7]])))
plt.show()
Figura 2 - Gráfico de dispersão com um polígono inserido.

O patches.Polygon também aceita o parâmetro closed, que recebe um bool onde True (padrão) indica que o polígono será fechado, e False indica que o polígono será aberto. Para exemplificar o comportamento, vou inserir cor para as bordas do polígono, e remover o seu preenchimento:
plt.figure(figsize=(8,6))
plt.scatter(x,y)
plt.gca().add_patch(patches.Polygon(xy=([[1,1], [2,2], [3,1], [2, 0.7]]), edgecolor='k', fill=False))
plt.show()
Figura 3 - Gráfico de dispersão com um polígono inserido.

Observe que o polígono está fechado, ou seja, as arestas estão todas conectadas. Mas, caso passe o parâmetro closed = False, obtemos este outro comportamento:
plt.figure(figsize=(8,6))
plt.scatter(x,y)
plt.gca().add_patch(patches.Polygon(xy=([[1,1], [2,2], [3,1], [2, 0.7]]), edgecolor='k', fill=False, closed=False))
plt.show()
Figura 4 - Gráfico de dispersão com um polígono inserido.

De qualquer forma, todas as arestas não precisam estar conectadas para que o polígono seja preenchido:
plt.figure(figsize=(8,6))
plt.scatter(x,y)
plt.gca().add_patch(patches.Polygon(xy=([[1,1], [2,2], [3,1], [2, 0.7]]), edgecolor='k', fill=True, closed=False))
plt.show()
Figura 5 - Gráfico de dispersão com um polígono inserido.

Edições
O patches.Polygon aceita uma série de parâmetros para a sua edição, sendo possível alterar a cor de preenchimento (color ou facecolor), remover o preenchimento (fill), inserir linhas (linestyle, linewidth, edgecolor), inserir estilos de preenchimento (hatch), adicionar transparência (alpha), determinar a ordem de plotagem (zorder), inserir nome para legenda (label), entre outros, de forma similar ao que vimos anteriormente.
Você encontra maiores detalhes na documentação.