Search code examples
pythonseaborndensity-plot

Can't display the seaborn distplot


I am trying to make a histogram and a density plot using the seaborn module of Python, and on the plot I am also trying to draw a vertical line at the mode. However, the resulting plot does not display any histogram and/or density curve. My code is below:

# a function to compute mode of the histograms shown in Figures `2` and `3` in the paper.
def compute_mode(layer_list):
    
    ax = sns.distplot(layer_list, hist=False, kde=True, kde_kws={'linewidth': 2})
    x = ax.lines[0].get_xdata()
    y = ax.lines[0].get_ydata()
    mode_idx = y.argmax()
    mode_x = x[mode_idx]
    plt.close()
        
    return mode_x

# function to plot the histogram of the layer lists.
def make_density(layer_list, color):

    
    # Plot formatting
    plt.xlabel('Median Stn. MC-Loss')
    plt.ylabel('Density')

    
    # Draw the histogram and fit a density plot.
    sns.distplot(layer_list, hist = True, kde = True,
                 kde_kws = {'linewidth': 2}, color=color)
    
    # compute mode of the histogram.
    mode_x = compute_mode(layer_list)
    
    # draw a vertical line at the mode of the histogram.
    plt.axvline(mode_x, color='blue', linestyle='dashed', linewidth=1.5)
    plt.text(mode_x, 0.16, 'mode: {:.4f}'.format(mode_x))

layer_list = [ 1.0,2.0,3.0,4.0,2.0,3.0,1.0,6.0,10.0,2.0]
make_density(layer_list, 'green')

enter image description here I think the problem arises from the line plt.axvline(mode_x, color='blue', linestyle='dashed', linewidth=1.5) and plt.text(mode_x, 0.16, 'mode: {:.4f}'.format(mode_x)).

What am I doing wrong here?

Thank you,


Solution

  • The main problem is that in compute_mode() plt.close() is called, which closes the plot that was just before created in make_density(). Note that sns.distplot is mainly a drawing function which shouldn't be used just for calculations. As the kde was already plotted in make_density(), ax.lines[0] can be passed to compue_mode() to extract the curve data without the need for creating the plot a second time.

    Some other remarks:

    • In seaborn 0.11, distplot has be deprecated, and is replaced by two functions: histplot which creates a histogram, optionally with a kde. And displot (without "T") which creates a grid of histogram/kdeplots. Apart from the name confusion, the kde_kws parameter of distplot is called line_kws in histplot, while kde_kws in histplot is meant for the function that calculates the KDE. Also, the kde curve always uses the same color as the histogram.
    • Seaborn's "axes level" functions return an ax that can be used for additional formatting. In your original code you added some labels before calling distplot, but as distplot also might change settings, it is safer to do all these formatting calls afterwards.
    • You might want to read about the object-oriented interface and the difference between ax.set_xlabel() and plt.xlabel().
    import matplotlib.pyplot as plt
    import seaborn as sns
    
    # a function to compute mode of the histograms shown in Figures `2` and `3` in the paper.
    def compute_mode(line_object):
        x = line_object.get_xdata()
        y = line_object.get_ydata()
        mode_idx = y.argmax()
        return x[mode_idx], y[mode_idx]
    
    # function to plot the histogram of the layer lists.
    def make_density(layer_list, color):
        # Draw the histogram and fit a density plot.
        ax = sns.histplot(layer_list, kde=True,
                          line_kws={'linewidth': 2}, color=color)
        # compute mode of the histogram.
        mode_x, mode_y = compute_mode(ax.lines[0])
    
        # draw a vertical line at the mode of the histogram.
        ax.axvline(mode_x, color='blue', linestyle='dashed', linewidth=1.5)
        ax.text(mode_x, mode_y, 'mode: {:.4f}'.format(mode_x))
        # Plot formatting
        ax.set_xlabel('Median Stn. MC-Loss')
        ax.set_ylabel('Density')
    
    layer_list = [1.0, 2.0, 3.0, 4.0, 2.0, 3.0, 1.0, 6.0, 10.0, 2.0]
    
    make_density(layer_list, 'green')
    plt.show()
    

    example plot