我正在绘制数据框的一列作为历史图。当我绘制时,我可以看到有3个峰,所以它是三峰的。如何注释图表以标记每个峰的值?
下面的我的代码并排绘制了两个直方图,第一个是具有异常值的数据场,第二个是不具有异常值的数据帧。
fig, ax = plt.subplots(ncols=2, figsize=(10,4))
df['price'].hist(bins=40,ax=ax[0])
df_nooutlier['price'].hist(bins=40,ax=ax[1])
df_nooutlier['price'].value_counts().head().plot(kind='line',linestyle='None', marker='o',color='r') #how can i plot such that i can see the labels
我希望每个峰都用其频率标记
答案 0 :(得分:1)
以下方法是查找模式及其索引(即x和y值以在其上绘制点和文本)。它使用np.histogram
来获取与直方图相对应的分布计数和bin划分。
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
def get_random_prices():
"""sample from three normal distributions"""
dist1 = np.random.normal(loc=5, scale=.3, size=1000)
dist2 = np.random.normal(loc=7, scale=.3, size=1000)
dist3 = np.random.normal(loc=11, scale=.3, size=1000)
min_price, max_price = 0, 20
all_dist = np.concatenate([dist1, dist2, dist3])
return all_dist[all_dist >= min_price][all_dist <= max_price]
def get_modes(counts, min_sep=.5):
# simple method to get mode values and locations (indexes)
# assume counts are already smoothed
# assume last mode is not past penultimate spot
modes = []
max_ct = 0
increasing = True
for i, count in enumerate(counts[1:]):
if count >= counts[i]:
max_ct = count
increasing = True
elif increasing:
modes.append((max_ct, i))
max_ct = 0
increasing = False
return modes
fig, ax = plt.subplots()
# create randomly generated data
df = pd.DataFrame({'price': get_random_prices()})
# get histogram data and display the same histogram
n_bins = 40
counts, divisions = np.histogram(df['price'], bins=n_bins)
df['price'].hist(bins=n_bins)
# find the peaks
modes = get_modes(counts)
# add the dots and labels for each peak, onto the histogram object
for mode, mode_index in modes:
ax.plot(divisions[mode_index], mode, 'ro')
# use offsets to make text appear away from the dots
# probably write logic to determine this instead of hard-coding
offset_x, offset_y = .1, 2
ax.text(divisions[mode_index] + offset_x, mode + offset_y, mode, color='r')
以下显示的modes
等于[(229, 5), (248, 15), (239, 35)]
,而np.__version__, pd.__version__
为('1.16.2', '0.24.2')
: