Search code examples
pythonmatplotlibcontour

plotting contours from a three column array


I have a three column array, contains two parameters which are the x and y axes, and the Chi-square of these two parameters. I should make a meshgrid of these two parameters and then plot 1-sigma, 2-sigma, and 3-sigma contours, considering the Chi-square values. How can I do it in matplotlib?

Here is my code: x (which is the second column in the "1.txt" file) and y (which is the third column) should be arranged from min to max, in order to make x and y axes, I thought it can be done using meshgrid. And z (the first column in the "1.txt" file) is the Chi-square.

import numpy as np 
import matplotlib.pyplot as plt
from matplotlib.mlab import griddata
x = np.genfromtxt('1.txt', usecols=(1))
y = np.genfromtxt('1.txt', usecols=(2))
z = np.genfromtxt('1.txt', usecols=(0))
plt.figure()
X, Y = np.meshgrid(x,y) 
Z= griddata(x,y,z,X,Y)
contour=plt.contour(X,Y,Z)
plt.show()

this code confront with the error: "RuntimeError: To use interp='nn' (Natural Neighbor interpolation) in griddata, natgrid must be installed. Either install it from http://github.com/matplotlib/natgrid or use interp='linear' instead." When I use interp='linear', running the code would last a long time without any result. Is there any way to solve this problem?


Solution

  • It looks like you are creating a "grid" of all values in your columns. Instead you would want to create a regular grid of numbers in an increasing order. E.g. using 100 values between the minimum and maximum of the data

    X = np.linspace(x.min(), x.max(), 100)
    Y = np.linspace(y.min(), y.max(), 100)
    Z = griddata(x, y, z, xi, yi, interp='linear')
    contour=plt.contour(X, Y, Z)
    

    Also see this example.

    Note however that matplotlib.mlab.griddata has been removed in newer versions of matplotlib, but is available with from scipy.interpolate import griddata, as shown in the new example, which also has the a newer option with axes.tricontour.

    Consider directly plotting a triangulated contour using your original values x,y,z,

    plt.tricontour(x, y, z)