График плотности Python Pandas - PullRequest
0 голосов
/ 11 января 2020

Я хочу создать график, похожий на график, прикрепленный ниже.

Мой фрейм данных построен в следующем формате:

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

Категория «популярность» можно заменить на 'streams' - единственное, что переменная streams имеет высокую дисперсию значений (от 0 до 10000+), и поэтому я считаю, что график плотности может выглядеть странно.

Однако мой первый вопрос как я могу построить график, подобный этому, в Pandas, при группировке по столбцу «Тип» и последующем создании графика плотности.

Я пробовал различные методы, но не нашел хорошего, чтобы установить sh моя цель.

enter image description here

Ответы [ 2 ]

2 голосов
/ 11 января 2020

Привет, вы можете попробовать следующий пример, я использовал случайные нормали только для этого примера, очевидно, было бы невозможно иметь отрицательные потоки. В любом случае отказ от ответственности закончился, вот код:

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')

enter image description here

Вы можете использовать Google 'Hex color picker', если хотите получить конкретный c Цвет # 000000 в формате, который я использовал в этом примере.

измените переменную 'alpha', если вы хотите изменить плотность отображения цвета, вы также можете поиграть с 'bin' в приведенном мною примере, так как это позволит вам сделать его лучше, если 50 слишком большой или маленький.

Надеюсь, это поможет, построение графиков в matplotlib может быть трудной задачей, но оно того стоит !!

1 голос
/ 13 января 2020

Чтобы дополнить ответ @ 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")

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...