Добавление разброса точек к ящику с использованием matplotlib
Я видел этот замечательный boxplot в в этой статье (Рис .2).
![A wonderful boxplot]()
Как вы можете видеть, это ящик, на который накладывается разброс черных точек: x индексирует черные точки (в случайном порядке), y - представляющая интерес переменная. Я хотел бы сделать что-то подобное, используя Matplotlib, но я понятия не имею, с чего начать. До сих пор ящики, которые я нашел в Интернете, менее прохладны и выглядят так:
![Usual boxplots]()
Документация matplotlib:
http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.boxplot
Способы раскраски ящиков:
https://github.com/jbmouret/matplotlib_for_papers#colored-boxes
Ответы
Ответ 1
То, что вы ищете, - это способ добавить дрожание к оси x.
Что-то вроде этого взято из здесь:
bp = titanic.boxplot(column='age', by='pclass', grid=False)
for i in [1,2,3]:
y = titanic.age[titanic.pclass==i].dropna()
# Add some random "jitter" to the x-axis
x = np.random.normal(i, 0.04, size=len(y))
plot(x, y, 'r.', alpha=0.2)
![enter image description here]()
Цитирование ссылки:
Один из способов добавить дополнительную информацию в блок-план - это оверлей фактические данные; это, как правило, наиболее подходит для малых или ряды данных среднего размера. Когда данные плотны, несколько трюков используемые выше, помогают визуализации:
- снижение уровня альфа, чтобы сделать частично прозрачными.
- добавление случайного "дрожания" вдоль оси х, чтобы избежать чрезмерного
Код выглядит следующим образом:
import pylab as P
import numpy as np
# Define data
# Define numBoxes
P.figure()
bp = P.boxplot(data)
for i in range(numBoxes):
y = data[i]
x = np.random.normal(1+i, 0.04, size=len(y))
P.plot(x, y, 'r.', alpha=0.2)
P.show()
Ответ 2
Расширение решения на Кирубасе и использование только matplotlib для сюжетной части (иногда мне сложно форматировать pandas plot с matplotlib).
from matplotlib import cm
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
# initialize dataframe
n = 200
ngroup = 3
df = pd.DataFrame({'data': np.random.rand(n), 'group': map(np.floor, np.random.rand(n) * ngroup)})
group = 'group'
column = 'data'
grouped = df.groupby(group)
names, vals, xs = [], [] ,[]
for i, (name, subdf) in enumerate(grouped):
names.append(name)
vals.append(subdf[column].tolist())
xs.append(np.random.normal(i+1, 0.04, subdf.shape[0]))
plt.boxplot(vals, labels=names)
ngroup = len(vals)
clevels = np.linspace(0., 1., ngroup)
for x, val, clevel in zip(xs, vals, clevels):
plt.scatter(x, val, c=cm.prism(clevel), alpha=0.4)
![enter image description here]()
Ответ 3
Существует функция, которая была создана для создания графика, который именно это... https://www.mathworks.com/matlabcentral/fileexchange/26508-notboxplot
Ответ 4
Как более простой, возможно, более новый вариант, вы можете использовать seaborn
swarmplot
.
import seaborn as sns
import matplotlib.pyplot as plt
sns.set(style="whitegrid")
tips = sns.load_dataset("tips")
ax = sns.boxplot(x="day", y="total_bill", data=tips, showfliers = False)
ax = sns.swarmplot(x="day", y="total_bill", data=tips, color=".25")
plt.show()
![enter image description here]()