pythonpython-3.xmatplotlibcontourf

Customizing contour plot using contourf( )


I am using matplotlib for countour plotting a function. I want to plot in such a way that up to a certain value of the function same colour is shown ( say, black ) and beyond that value of the function color gradient is shown. I am new to contour plotting and I don't know how to achieve this. Here is a code sample. This code results into continuously varying colors. I want a fixed color upto threshold and beyond that the color should vary in a continuous manner.

x = np.linspace(0,50, 1000)
y = np.linspace(0, 20, 1000)
[X,Y] = np.meshgrid(x,y)

Z = np.sin(X) + np.cos(Y)
threshold = 1.03
lvls = np.linspace((Z).min(),(Z).max(),3000)
contour_plot=plt.contourf(X,Y,Z,levels=lvls,cmap='viridis')
colorbar = plt.colorbar(contour_plot)

Solution

  • See below my solution, based on example in matplotlib documentation.

    import numpy as np
    
    import matplotlib
    import matplotlib.pyplot as plt
    from matplotlib.colors import ListedColormap, LinearSegmentedColormap
    
    # Define data
    x = np.linspace(0,50, 100)
    y = np.linspace(0, 20, 100)
    [X,Y] = np.meshgrid(x,y)
    
    Z = np.sin(X) + np.cos(Y)
    threshold = 1.03
    
    # Get the colormap and the colors inside it
    viridis = matplotlib.colormaps.get_cmap('viridis')
    n_of_colors = 500 # with this you can control the "sampling frequency" of the original colormap
    newcolors = viridis(np.linspace(0, 
                                    1, 
                                    n_of_colors 
                        )) 
    black = np.array([0.0, 0.0, 0.0, 1])
    
    # Get the index corresponding to the threshold value
    threshold_idx = int(((threshold - Z.min()) / (Z.max() - Z.min())) * n_of_colors)
    # Set all the colors below the threshold (index) to black
    newcolors[:threshold_idx, :] = black
    # Create a new colormaps with the colors you just defined
    newcmp = ListedColormap(newcolors)
    
    # Plot
    lvls = np.linspace((Z).min(),(Z).max(),3000)
    contour_plot = plt.contourf(X,Y,Z,levels=lvls,cmap=newcmp)
    colorbar = plt.colorbar(contour_plot)
    
    plt.show()
    

    Resulting in the following image Contour with thresholded color map

    Side note. The grid you gave in your MWE was quite heavy to be processed, had to downscale it.

    Hope this helps!