No RI, é possível criar a saída desejada fazendo:
data = c(rep(1.5, 7), rep(2.5, 2), rep(3.5, 8),
rep(4.5, 3), rep(5.5, 1), rep(6.5, 8))
plot(density(data, bw=0.5))
Em python (com matplotlib), o mais próximo que cheguei foi com um histograma simples:
import matplotlib.pyplot as plt
data = [1.5]*7 + [2.5]*2 + [3.5]*8 + [4.5]*3 + [5.5]*1 + [6.5]*8
plt.hist(data, bins=6)
plt.show()
Eu também tentei o parâmetro normed = True, mas não consegui nada além de tentar ajustar um gaussiano ao histograma.
Minhas últimas tentativas foram por aí scipy.stats
e gaussian_kde
, seguindo exemplos na web, mas não tive sucesso até agora.
seaborn
stackoverflow.com/a/32803224/1922302Respostas:
Sven mostrou como usar a classe
gaussian_kde
de Scipy, mas você notará que não se parece muito com o que você gerou com R. Isso ocorre porquegaussian_kde
tenta inferir a largura de banda automaticamente. Você pode brincar com a largura de banda mudando a funçãocovariance_factor
dagaussian_kde
classe. Primeiro, aqui está o que você obtém sem alterar essa função:No entanto, se eu usar o seguinte código:
eu recebo
o que é bem parecido com o que você está recebendo da R. O que eu fiz?
gaussian_kde
usa uma função mutável,covariance_factor
para calcular sua largura de banda. Antes de alterar a função, o valor retornado por covariance_factor para esses dados era de cerca de 0,5. Reduzir isso reduziu a largura de banda. Tive que chamar_compute_covariance
depois de alterar essa função para que todos os fatores fossem calculados corretamente. Não é uma correspondência exata com o parâmetro bw de R, mas espero que ajude você a ir na direção certa.fonte
set_bandwidth
método e umbw_method
argumento de construtor foram adicionados a gaussian_kde no scipy 0.11.0 por edição de 1619Cinco anos depois, quando pesquisei "como criar um gráfico de densidade do kernel usando python" no Google, esse tópico ainda aparece no topo!
Hoje, uma maneira muito mais fácil de fazer isso é usar o seaborn , um pacote que oferece muitas funções convenientes de plotagem e bom gerenciamento de estilo.
fonte
bw=0.5
é dado?bw
parâmetro significa largura de banda. Eu estava tentando corresponder à configuração de OP (veja seu primeiro exemplo de código original). Para uma explicação detalhada sobre quaisbw
controles, consulte en.wikipedia.org/wiki/… . Basicamente, ele controla o quão suave você deseja que o gráfico de densidade seja. Quanto maior for o bw, mais suave será.TypeError: slice indices must be integers or None or have an __index__ method
Opção 1:
Use
pandas
dataframe plot (construído sobrematplotlib
):Opção 2:
Uso
distplot
deseaborn
:fonte
pandas.DataFrame
, pode usarpandas.Series(data).plot(kind='density')
@Anake, não precisa definir df.plot.density como uma etapa separada; pode simplesmente passar seubw_method
kwarg parapd.Series(data).plot(kind='density', bw_method=0.5)
Talvez tente algo como:
Você pode facilmente substituir
gaussian_kde()
por uma estimativa de densidade de kernel diferente.fonte
O gráfico de densidade também pode ser criado usando matplotlib: A função plt.hist (dados) retorna os valores y e x necessários para o gráfico de densidade (consulte a documentação https://matplotlib.org/3.1.1/api/_as_gen/ matplotlib.pyplot.hist.html ). Consequentemente, o código a seguir cria um gráfico de densidade usando a biblioteca matplotlib:
Este código retorna o seguinte gráfico de densidade
fonte