繁体   English   中英

密度图 Python Pandas

[英]Density Plot Python Pandas

我想创建一个看起来像下面附加的图的图。

我的数据框是以这种格式构建的:

   Playlist  Type        Streams
0  a         classical   94  
1  b         hip-hop     12
2  c         classical   8

'popularity' 类别可以由 'streams' 代替 - 唯一的问题是流变量具有很高的值方差(从 0 到 10,000+),因此我相信密度图可能看起来很奇怪。

但是,我的第一个问题是,当按“类型”列分组然后创建密度图时,如何在 Pandas 中绘制与此类似的图形。

我尝试了各种方法,但没有找到一个好的方法来确定我的目标。

在此处输入图片说明

嗨,您可以尝试以下示例,我仅在此示例中使用了 randon 法线,显然不可能有负流。 无论如何免责声明,这里是代码:

import random 

categories = ['classical','hip-hop','indiepop','indierock','jazz'
          ,'metal','pop','rap','rock']

df = pd.DataFrame({'Type':[random.choice(categories) for _ in range(10000)],
              'stream':[random.normalvariate(0,random.randint(0,15)) for _ in 
               range(10000)]})

###split the data into groups based on types
g = df.groupby('Type')



###access the classical group 
classical = g.get_group('classical')
plt.figure(figsize=(15,6))
plt.hist(classical.stream, histtype='stepfilled', bins=50, alpha=0.2,
     label="Classical Streams", color="#D73A30", density=True)
plt.legend(loc="upper left")

###hip hop

hiphop = g.get_group('hip-hop')

plt.hist(hiphop.stream, histtype='stepfilled', bins=50, alpha=0.2,
     label="hiphop Streams", color="#2A3586", density=True)
plt.legend(loc="upper left")

###indie pop
indiepop = g.get_group('indiepop')

plt.hist(indiepop.stream, histtype='stepfilled', bins=50, alpha=0.2,
     label="indie pop streams", color="#5D271B", density=True)
plt.legend(loc="upper left")


#indierock

indierock = g.get_group('indierock')

plt.hist(indierock.stream, histtype='stepfilled', bins=50, alpha=0.2,
     label="indie rock Streams", color="#30A9D7", density=True)
plt.legend(loc="upper left")


##jazz
jazz = g.get_group('jazz')
plt.hist(jazz.stream, histtype='stepfilled', bins=50, alpha=0.2,
     label="jazz Streams", color="#30A9D7", density=True)
plt.legend(loc="upper left")


####you can add other here if you wish

##modify this to control x-axis, possibly useful for high-variance data
plt.xlim([-20,20])

plt.title('Distribution of Streams by Genre')
plt.xlabel('Count')
plt.ylabel('Density')

在此处输入图片说明

如果您想以我在本示例中使用的格式获取特定的“#000000”颜色,您可以使用 Google 'Hex color picker'。

如果您想更改颜色显示的密度,请修改变量 'alpha',您也可以在我提供的示例中使用 'bins',因为如果 50 太大或太小,这将使您看起来更好。

我希望这会有所帮助,在 matplotlib 中绘图可能会很痛苦,但它肯定是值得的!!

为了增加@Student240 的答案,您可以使用 seaborn 库,它可以轻松拟合“核密度估计”。 换句话说,要有与您的问题相似的平滑曲线,而不是分箱直方图。 这是通过KDEplot类完成的。 一个相关的绘图类型是distplot ,它给出了 KDE 估计值,但也显示了直方图箱。

我的答案的另一个不同之处是在 matplotlib/seaborn 中使用显式面向对象的方法。 这涉及最初使用plt.subplots()而不是fig.hist的隐式方法声明图形和轴对象。 有关更多详细信息,请参阅这个非常好的教程

import matplotlib.pyplot as plt
import seaborn as sns

## This block of code is copied from Student240's answer:
import random 

categories = ['classical','hip-hop','indiepop','indierock','jazz'
          ,'metal','pop','rap','rock']

# NB I use a slightly different random variable assignment to introduce a bit more variety in my random numbers.
df = pd.DataFrame({'Type':[random.choice(categories) for _ in range(1000)],
              'stream':[random.normalvariate(i,random.randint(0,15)) for i in 
               range(1000)]})


###split the data into groups based on types
g = df.groupby('Type')

## From here things change as I make use of the seaborn library
classical = g.get_group('classical')
hiphop = g.get_group('hip-hop')
indiepop = g.get_group('indiepop')
indierock = g.get_group('indierock')
fig, ax = plt.subplots()

ax = sns.kdeplot(data=classical['stream'], label='classical streams', ax=ax)
ax = sns.kdeplot(data=hiphop['stream'], label='hiphop streams', ax=ax)
ax = sns.kdeplot(data=indiepop['stream'], label='indiepop streams', ax=ax)

# for this final one I use the shade option just to show how it is done:
ax = sns.kdeplot(data=indierock['stream'], label='indierock streams', ax=ax, shade=True)

ax.set_xtitle('Count')
ax.set_ytitle('Density')
ax.set_title('KDE plot example from seaborn")

在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM