7

I am trying to write a function to produce Matlab style correlation plots using matplotlib in Python 3.4 (example here). However, I want to change the plot so that the diagonal subplots display the name of the variable, the lower triangle subplots display the Pearson correlation coefficient, and the upper triangle subplots display a scatter plot. Below is some code to generate sample data and the function I wrote. It displays the appropriate 4x4 grid of subplots with variable names and correlation coefficients in the correct place, but the scatter plots do not show up.

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()

In an attempt to identify the source of the problem, I manually reconstructed the plot for a 2 variable case using the following code, which produces the desired plot:

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()

Since this works, I hypothesized that the problem had nothing to do with mixing text and data in the subplots. I wrote the next function to test populating the subplots using a for loop, and it produces a scatter plot in each subplot as expected.

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()

Next, I tried to populate only a subset of the subplots using for loops. This produces a blank grid as follows.

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()

This leads me to believe that there is some error related to the for loops and how the scatter plots are being created, but I haven't been able to find the error yet.

12
  • Hi and welcome to SO! Kudos for creating a MCVE, it is much appreciated. It's not 100% functional, however, you need to change the definition of names to names = ['Var' + str(i) for i in range(data.shape[1])] (string to 'str' and you forgot the range). Once I did that and added a call to 'corrplot', I actually got the result to work just fine. What version of matplotlib are you using? Commented Apr 2, 2015 at 15:09
  • I'm using matplotlib 1.4.3. I use the Anaconda distribution and updated everything yesterday to make sure an old version wasn't the issue. Commented Apr 2, 2015 at 15:13
  • Do you have any changes to the default rcParams? That's the only other thing I can think of that might make those dots disappear. Try putting plt.rcdefaults() at the top and see what you get. Commented Apr 2, 2015 at 15:17
  • I haven't made any changes to rcParams. Adding that at the top didn't change anything. Commented Apr 2, 2015 at 15:19
  • I'm afraid I'm a bit at a loss then ... even your 'test2', which is blank for you, looks like it's supposed to for me. What backend are you using, what OS? Commented Apr 2, 2015 at 15:23

1 Answer 1

1

Your code shows exactly the desired plot. I think your version of matplolib didn’t recognize the marker = '.'

You could try to plot with default marker (without marker = '.') or replace it with marker = 'o'

Sign up to request clarification or add additional context in comments.

1 Comment

Ultimately I found a different solution that didn't use matplotlib. However, revisiting this with a newer version of matplotlib, it works perfectly. Thanks for the answer; it made me revisit this and realize that it actually does work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.