O matplotlib tem uma function para desenhar linhas diagonais em coordenadas de eixo?

Os eixos de Matplotlib têm as funções axhline e axvline para desenhar linhas horizontais ou verticais em uma dada coordenada y ou x (respectivamente) independentemente da escala de dados em um Eixo.

Existe uma function semelhante para traçar uma diagonal constante? Por exemplo, se eu tiver um gráfico de dispersão de variables ​​com um domínio semelhante, geralmente é útil saber se elas estão acima ou abaixo da linha de y = x :

 mean, cov = [0, 0], [(1, .6), (.6, 1)] x, y = np.random.multivariate_normal(mean, cov, 100).T y += x + 1 f, ax = plt.subplots(figsize=(6, 6)) ax.scatter(x, y, c=".3") ax.plot([-3, 3], [-3, 3], ls="--", c=".3") ax.set(xlim=(-3, 3), ylim=(-3, 3)) 

insira a descrição da imagem aqui

É claro que isso pode ser feito programaticamente, pegando-se os limites do eixo, ( ax.get_xlim() , etc.), mas isso a) leva alguns passos extras eb) é frágil nos casos em que mais dados podem acabar no enredo e mudar os limites. (Na verdade, em alguns casos, basta adicionar a própria linha constante para alongar os eixos).

Seria preferível fazer apenas, por exemplo, ax.axdline(ls="--", c=".3") , mas não está claro se algo como isto existe na base de código do matplotlib. Tudo o que você precisaria fazer seria modificar o código axhline para plotar de [0, 1] nas coordenadas dos eixos para x y , eu acho.

Plotando uma linha diagonal com base a partir do canto inferior esquerdo para o canto superior direito da canvas é bastante simples, você pode simplesmente usar ax.plot(ax.get_xlim(), ax.get_ylim(), ls="--", c=".3") . O método ax.get_xlim() simplesmente retornará os valores atuais do eixo x (e similarmente para o eixo y).

No entanto, se você quiser fazer zoom usando o gráfico, ele se torna um pouco mais complicado, pois a linha diagonal que você desenhou não será alterada para corresponder aos novos xlims e ylims.

Nesse caso, você pode usar callbacks para verificar quando os xlims (ou ylims) foram alterados e alterar os dados na sua linha diagonal de acordo (conforme mostrado abaixo). Eu encontrei os methods para retornos de chamada neste exemplo . Mais informações também podem ser encontradas aqui

 import numpy as np import matplotlib.pyplot as plt mean, cov = [0, 0], [(1, .6), (.6, 1)] x, y = np.random.multivariate_normal(mean, cov, 100).T y += x + 1 f, ax = plt.subplots(figsize=(6, 6)) ax.scatter(x, y, c=".3") ax.set(xlim=(-3, 3), ylim=(-3, 3)) # Plot your initial diagonal line based on the starting # xlims and ylims. diag_line, = ax.plot(ax.get_xlim(), ax.get_ylim(), ls="--", c=".3") def on_change(axes): # When this function is called it checks the current # values of xlim and ylim and modifies diag_line # accordingly. x_lims = ax.get_xlim() y_lims = ax.get_ylim() diag_line.set_data(x_lims, y_lims) # Connect two callbacks to your axis instance. # These will call the function "on_change" whenever # xlim or ylim is changed. ax.callbacks.connect('xlim_changed', on_change) ax.callbacks.connect('ylim_changed', on_change) plt.show() 

Observe que, se você não quiser que a linha diagonal mude com o zoom, basta remover tudo abaixo de diag_line, = ax.plot(...

Desenhar uma diagonal do canto inferior esquerdo para os cantos superiores direitos do seu enredo seria realizado pela seguinte

ax.plot([0, 1], [0, 1], transform=ax.transAxes)

Usando transform=ax.transAxes , as coordenadas x e y fornecidas são interpretadas como coordenadas de eixos em vez de coordenadas de dados .

Isso, como @fqq apontou, é apenas a linha de identidade quando seus limites x e y são iguais. Para desenhar a linha y=x forma que ela sempre se estenda até os limites de sua plotagem, uma abordagem semelhante à dada por @Ffisegydd funcionaria e pode ser escrita como a seguinte function.

 def add_identity(axes, *line_args, **line_kwargs): identity, = axes.plot([], [], *line_args, **line_kwargs) def callback(axes): low_x, high_x = axes.get_xlim() low_y, high_y = axes.get_ylim() low = max(low_x, low_y) high = min(high_x, high_y) identity.set_data([low, high], [low, high]) callback(axes) axes.callbacks.connect('xlim_changed', callback) axes.callbacks.connect('ylim_changed', callback) return axes 

Exemplo de uso:

 import numpy as np import matplotlib.pyplot as plt mean, cov = [0, 0], [(1, .6), (.6, 1)] x, y = np.random.multivariate_normal(mean, cov, 100).T y += x + 1 f, ax = plt.subplots(figsize=(6, 6)) ax.scatter(x, y, c=".3") add_identity(ax, color='r', ls='--') plt.show() 

Se os eixos estiverem no intervalo [0,1] , pode ser resolvido desta forma:

 ident = [0.0, 1.0] plt.plot(ident,ident)