1

Having the following line in my plot code

ax.plot(x, pdf_individual, '--k', label = "single Gaussians")

, with pdf_individual being a list of lists, results in this picture:

enter image description here

Is there a way to just have "single Gaussians" once in the labels, instead of 6 times, which is the amount of single Gaussians for the Gaussian Mixture Model?

This is the whole post with the suggested solution

import matplotlib as mpl
import matplotlib.ticker as mtick
from matplotlib.lines import Line2D
mpl.rcParams['figure.dpi'] = 600

test_input =  input_list # THIS IS A 1D LIST with a few hundred items
X = np.asarray(test_input).reshape(-1,1)

N = np.arange(1, 11)
models = [None for i in range(len(N))]
for i in range(len(N)):
    models[i] = GaussianMixture(N[i]).fit(X)

# compute the AIC and the BIC
AIC = [m.aic(X) for m in models]
BIC = [m.bic(X) for m in models]



fig = plt.figure(figsize=(12, 4))
fig.subplots_adjust(left=0.1, right=0.9,
                    bottom=0.21, top=0.9, wspace=0.3)



ax = fig.add_subplot(131)
M_best = models[np.argmin(AIC)]
comp_count = str(M_best)
x = np.linspace(0, 0.1, 100)
logprob = M_best.score_samples(x.reshape(-1, 1))
responsibilities = M_best.predict_proba(x.reshape(-1, 1))
pdf = np.exp(logprob)
pdf_individual = responsibilities * pdf[:, np.newaxis]

                        
left, width = .245, .5
bottom, height = .4, .5
right = left + width
top = bottom + height
plt.setp( ax.xaxis.get_majorticklabels(), rotation=-45, ha="left" )
ax.yaxis.set_major_formatter(mtick.PercentFormatter())
ax.hist(X, 30, density=True, histtype='stepfilled', alpha=0.4, label="Data")
ax.plot(x, pdf, '-k', color = "red", label='GMM')
for i, pdf_individual in enumerate(pdf_individual):
    ax.plot(x, pdf_individual, '--k', label = "single Gaussians" if i == 0 else "")
#for pdf in pdf_individual[1:]: ax.plot(x, pdf, '--k')
ax.text(right, top, "Anzahl Komponenten: " + comp_count[-2],
        horizontalalignment='center',
        verticalalignment='bottom',
        transform=ax.transAxes)

ax.set_xlabel('$x$')
ax.set_ylabel('$p(x)$')

plt.legend()

plt.show()

It results in this error:

ValueError: x and y must have same first dimension, but have shapes (100,) and (6,)

EDIT:

Putting

pdf_individual = np.transpose(pdf_individual)

makes the code above work

Stefan 44
  • 157
  • 1
  • 9
  • 1
    I normally do it like this: `ax.plot(x, pdf_individual[0], '--k', label = "single Gaussians")` and then `for pdf in pdf_individual[1:]: ax.plot(x, pdf, '--k')`. It's a lot of boilerplate but it works – ForceBru Mar 27 '22 at 13:24
  • Does this answer your question? [Duplicate items in legend in matplotlib?](https://stackoverflow.com/questions/19385639/duplicate-items-in-legend-in-matplotlib) In essence, what ForceBru does in one line: `[ax.plot(x, y, '--k', label = "single Gaussians" if not i else "") for i, y in enumerate(pdf_individual)]` – Mr. T Mar 27 '22 at 13:48
  • @ForceBru I get this error: ValueError: x and y must have same first dimension, but have shapes (100,) and (7,) This error makes sense to me, i just wonder why the whole code worked. Since len of the pdf_individual is 100, so its 100 lists with 6 values. I would have expected to have 6 lists with 100 values instead actually – Stefan 44 Mar 27 '22 at 13:53
  • @Mr.T i get the same error unfortunately.. – Stefan 44 Mar 27 '22 at 13:57
  • 1
    @Stefan44, I've come across that issue before - [there's an explanation somewhere in the `plot` source code](https://stackoverflow.com/questions/71213425/what-is-being-plotted-by-plt-plot-with-a-tuple-argument/71216046#71216046). In the first case, `matplotlib` figures it out but in the second you are explicitly describing how to iterate. Can you make `pdf_individual` a numpy array and transpose it? – ramzeek Mar 27 '22 at 13:59
  • Obviously, as it is the same approach. The error message, output, and your description of the data do not match. If you want help, you should provide [a minimal, complete, and reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). – Mr. T Mar 27 '22 at 14:01
  • i will update the post, one second – Stefan 44 Mar 27 '22 at 14:08
  • i don't really know how to reduce the code so that it remains complete enough for the issue, since i don't really get where the transformation of the lists happens as I got most of the code from here: http://www.astroml.org/book_figures/chapter4/fig_GMM_1D.html However, any simple Input list should give you the same results – Stefan 44 Mar 27 '22 at 14:15
  • @ramzeek transposing worked! – Stefan 44 Mar 27 '22 at 14:17

0 Answers0