In Panda’s doe ik:
bp = p_df.groupby('class').plot(kind='kde')
p_df
is een dataframe
-object.
Dit levert echter twee plots op, één voor elke klasse.
Hoe forceer ik één plot met beide klassen in dezelfde plot?
Antwoord 1, autoriteit 100%
Versie 1:
U kunt uw as maken en vervolgens het trefwoord ax
van DataFrameGroupBy.plot
om alles aan deze assen toe te voegen:
import matplotlib.pyplot as plt
p_df = pd.DataFrame({"class": [1,1,2,2,1], "a": [2,3,2,3,2]})
fig, ax = plt.subplots(figsize=(8,6))
bp = p_df.groupby('class').plot(kind='kde', ax=ax)
Dit is het resultaat:
Helaas is de aanduiding van de legende hier niet zo logisch.
Versie 2:
Een andere manier is om door de groepen te lopen en de curven handmatig te plotten:
classes = ["class 1"] * 5 + ["class 2"] * 5
vals = [1,3,5,1,3] + [2,6,7,5,2]
p_df = pd.DataFrame({"class": classes, "vals": vals})
fig, ax = plt.subplots(figsize=(8,6))
for label, df in p_df.groupby('class'):
df.vals.plot(kind="kde", ax=ax, label=label)
plt.legend()
Op deze manier kunt u eenvoudig de legenda beheren. Dit is het resultaat:
Antwoord 2, autoriteit 16%
Een andere benadering is het gebruik van de module seaborn
. Dit zou de twee dichtheidsschattingen op dezelfde assen plotten zonder een variabele op te geven om de assen als volgt vast te houden (met behulp van een dataframe-instelling van het andere antwoord):
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
# data to create an example data frame
classes = ["c1"] * 5 + ["c2"] * 5
vals = [1,3,5,1,3] + [2,6,7,5,2]
# the data frame
df = pd.DataFrame({"cls": classes, "indices":idx, "vals": vals})
# this is to plot the kde
sns.kdeplot(df.vals[df.cls == "c1"],label='c1');
sns.kdeplot(df.vals[df.cls == "c2"],label='c2');
# beautifying the labels
plt.xlabel('value')
plt.ylabel('density')
plt.show()
Dit resulteert in de volgende afbeelding.
Antwoord 3, autoriteit 13%
import matplotlib.pyplot as plt
p_df.groupby('class').plot(kind='kde', ax=plt.gca())
Antwoord 4, autoriteit 5%
Misschien kun je dit proberen:
fig, ax = plt.subplots(figsize=(10,8))
classes = list(df.class.unique())
for c in classes:
df2 = data.loc[data['class'] == c]
df2.vals.plot(kind="kde", ax=ax, label=c)
plt.legend()
Antwoord 5
- Er zijn twee eenvoudige methoden om elke groep in dezelfde plot te plotten.
- Bij gebruik van
pandas.DataFrame.groupby
moet de te plotten kolom (bijv. de aggregatiekolom) worden opgegeven. - Gebruik
seaborn.kdeplot
ofseaborn.displot
en geef de parameterhue
op
- Bij gebruik van
- Met behulp van
pandas v1.2.4
,matplotlib 3.4.2
,seaborn 0.11.1
- De OP is specifiek voor het plotten van de
kde
, maar de stappen zijn hetzelfde voor veel plottypes (bijv.kind='line'
,sns.lineplot
, enz.).
Import en voorbeeldgegevens
- Voor de voorbeeldgegevens staan de groepen in de kolom
'kind'
en wordt dekde
van'duration'
uitgezet, negeren van'waiting'
.
import pandas as pd
import seaborn as sns
df = sns.load_dataset('geyser')
# display(df.head())
duration waiting kind
0 3.600 79 long
1 1.800 54 short
2 3.333 74 long
3 2.283 62 short
4 4.533 85 long
Plot met pandas.DataFrame.plot
- Vorm de gegevens opnieuw met
.groupby
of.pivot
.groupby
- Geef de aggregatiekolom op,
['duration']
enkind='kde'
.
ax = df.groupby('kind')['duration'].plot(kind='kde', legend=True)
.pivot
ax = df.pivot(columns='kind', values='duration').plot(kind='kde')
Plot met seaborn.kdeplot
- Specificeer
hue='kind'
ax = sns.kdeplot(data=df, x='duration', hue='kind')
Plot met seaborn.displot
- Geef
hue='kind'
enkind='kde'
op
fig = sns.displot(data=df, kind='kde', x='duration', hue='kind')