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')
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,
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:
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.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.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()