2015-04-02 14 views
7

Sto provando a scrivere una funzione per produrre grafici di correlazione in stile Matlab utilizzando matplotlib in Python 3.4 (esempio here). Tuttavia, voglio cambiare la trama in modo che le sottotrame diagonali visualizzino il nome della variabile, le sottotrame del triangolo inferiore visualizzino il coefficiente di correlazione di Pearson e le sottotrame del triangolo superiore mostrino un grafico a dispersione. Di seguito è riportato un codice per generare dati di esempio e la funzione che ho scritto. Visualizza la griglia 4x4 appropriata di sottotrame con nomi di variabili e coefficienti di correlazione nella posizione corretta, ma i grafici a dispersione non vengono visualizzati.I grafici a dispersione matplotlib non vengono visualizzati quando popolati utilizzando per il ciclo

import numpy as np 
import matplotlib.pyplot as plt 

means = [0, 1, 0, 2] 
sig = [[1, 0.5, 0, -0.1], [0.5, 3, 0, 0.2], [0, -0.1, 1, -0.3], [-0.1, 0.2, -0.3, 1]] 
data = np.random.multivariate_normal(means, sig, 50) 
names = ['Var' + str(i) for i in range(data.shape[1])] 

def corrplot(data, names): 
    corrMat = np.corrcoef(data, rowvar = 0) 
    numVars = data.shape[1] 

    fig, ax = plt.subplots(numVars, numVars, sharex = "col", sharey = "row") 
    fig.subplots_adjust(wspace = 0, hspace = 0) 

    for i in range(numVars): 
     for j in range(numVars): 
      if i == j: # On the diagonal 
       ax[i, j].text(0.5, 0.5, names[i], transform = ax[i, j].transAxes) 
      elif i < j: # In the upper triangle 
       ax[i, j].scatter(data[:, i], data[:, j], marker = '.') 
      elif i > j: # In the lower triangle 
       ax[i, j].text(0.5, 0.5, str(round(corrMat[i, j], 3)), transform = ax[i, j].transAxes) 
    plt.show() 

Nel tentativo di identificare l'origine del problema, ho ricostruito manualmente la trama per un caso variabile 2 utilizzando il codice seguente, che produce la trama desiderata:

fig, ax = plt.subplots(2, 2, sharex = "col", sharey = "row") 
fig.subplots_adjust(wspace = 0, hspace = 0) 
ax[0, 0].text(0.5, 0.5, 'Var0', transform = ax[0, 0].transAxes) 
ax[0, 1].scatter(data[:, i], data[:, j], marker = '.') 
ax[1, 0].text(0.5, 0.5, '0.5', transform = ax[1, 0].transAxes) 
ax[1, 1].text(0.5, 0.5, 'Var1', transform = ax[1, 1].transAxes) 
plt.show() 

Da questo funziona, Ho ipotizzato che il problema non avesse nulla a che fare con il mixaggio di testo e dati nelle sottotrame. Ho scritto la funzione successiva per testare il popolamento delle sottotrame usando un ciclo for, e produce un grafico a dispersione in ogni sottotrama come previsto.

def test1(data): 
    numVars = data.shape[1] 
    fig, ax = plt.subplots(numVars, numVars, sharex = "col", sharey = "row") 
    fig.subplots_adjust(wspace = 0, hspace = 0) 

    for i in range(numVars): 
     for j in range(numVars): 
      ax[i, j].scatter(data[:, i], data[:, j], marker = '.') 
    plt.show() 

Successivamente, ho provato a popolare solo un sottoinsieme delle sottotrame utilizzando per cicli. Ciò produce una griglia vuota come segue.

def test2(data): 
    numVars = data.shape[1] 
    fig, ax = plt.subplots(numVars, numVars, sharex = "col", sharey = "row") 
    fig.subplots_adjust(wspace = 0, hspace = 0) 

    for i in range(numVars): 
     for j in range(i + 1, numVars): 
      ax[i, j].scatter(data[:, i], data[:, j], marker = '.') 
    plt.show() 

Questo mi porta a credere che ci sia qualche errore relativo al cicli for e come vengono creati i grafici a dispersione, ma non sono stato in grado di trovare l'errore ancora.

+0

Ciao e benvenuto al SO! Complimenti per aver creato un MCVE, è molto apprezzato. Non è funzionale al 100%, tuttavia, è necessario cambiare la definizione dei nomi in 'names = ['Var' + str (i) per i in range (data.shape [1])]' (stringa su 'str' e hai dimenticato il 'range'). Una volta che l'ho fatto e ho aggiunto una chiamata a "corrplot", in realtà ho ottenuto che il risultato funzionasse perfettamente. Quale versione di matplotlib stai usando? – Ajean

+0

Sto usando matplotlib 1.4.3. Io uso la distribuzione di Anaconda e ho aggiornato tutto ieri per assicurarmi che una vecchia versione non fosse il problema. –

+0

Sono state apportate modifiche alle impostazioni predefinite rcParams? Questa è l'unica altra cosa che posso pensare che possa far sparire quei punti. Prova a mettere 'plt.rcdefaults()' in cima e guarda cosa ottieni. – Ajean

risposta

1

Il codice mostra esattamente la trama desiderata. Credo che la vostra versione di matplolib non ha riconosciuto il marker = '.'

Si potrebbe provare a tracciare con un pennarello di default (senza marker = '.') o sostituirla con marker = 'o'

+0

Alla fine ho trovato una soluzione diversa che non utilizzava matplotlib. Tuttavia, rivisitando questo con una versione più recente di matplotlib, funziona perfettamente. Grazie per la risposta; mi ha fatto rivisitare questo e rendermi conto che in realtà funziona. –

Problemi correlati