在 matplotlib 中的垂直线之间绘制文本框和填充颜色 python
plot textboxes and fill colors between vertical lines in matplotlib python
基于另一个 我得到了这个代码:
data = np.random.normal(loc=0.0, scale=1.0, size=2000)
df_data = pd.DataFrame(data)
import numpy as np
import scipy
import pandas as pd
from scipy.stats import norm
import matplotlib.pyplot as plt
def _plot(df):
for col in df.columns:
n_bins = 50
fig, axes = plt.subplots(figsize=(12,6))
n, bins, patches = axes.hist(df[col], n_bins, density=True, alpha=.1, edgecolor='black' )
mu = df[col].mean()
sigma = df[col].std()
pdf = 1/(sigma*np.sqrt(2*np.pi))*np.exp(-(bins-mu)**2/(2*sigma**2))
#probability density function
axes.plot(bins, pdf, color='green', alpha=.6)
#dashed lines
plt.axvline(np.mean(df_data[0]),color='b', linestyle='-.')
plt.axvline(np.mean(df_data[0]-sigma),color='b', linestyle='-.')
plt.axvline(np.mean(df_data[0]-2*sigma),color='b', linestyle='-.')
plt.axvline(np.mean(df_data[0]-3*sigma),color='b', linestyle='-.')
plt.axvline(min(df_data[0]),color='r', linestyle='-.')
plt.axvline(np.mean(df_data[0]+sigma),color='b', linestyle='-.')
plt.axvline(np.mean(df_data[0]+2*sigma),color='b', linestyle='-.')
plt.axvline(np.mean(df_data[0]+3*sigma),color='b', linestyle='-.')
plt.axvline(max(df_data[0]),color='r', linestyle='-.')
plt.ylabel('Probability Density')
plt.xlabel('Values')
print(mu)
print(sigma)
_plot(df_data)
哪个returns我这个好情节:
如您所见,蓝色垂直线表示由标准差的倍数设置的边界。我想添加以下信息和颜色编码,我现在将其快速放入 powerpoint 中:
我试图弄乱 plt.fill_between
函数,但没有真正得到任何有用的东西。我也不知道怎么写东西,比如这里的 mu+l*sigma,above plot。我怎样才能根据现有的获得第二张图片?
编辑:
由@Trenton McKinney
解决
将新框放入彩色框内:
for i, (x, c) in enumerate(locs[:-1]):
axes.axvspan(x, locs[i + 1][0], alpha=0.2, color=c)
tx = (x + locs[i + 1][0]) / 2
axes.text(tx, y1/2, f'Zustand {i + 1}', {'ha': 'center', 'va': 'center'}, rotation=90)
if i<4:
axes.text(tx, y1/1.25, r"$\mu$" + "-" + f"{4-i}"+ "$\cdot$" + "$\sigma$" , {'ha': 'center', 'va': 'center'}, rotation=90, bbox=dict(facecolor='white', alpha=0.8, edgecolor='black'))
else:
axes.text(tx, y1/1.25, r"$\mu$" + "+" + f"{i-4 + 1}"+ "$\cdot$" + "$\sigma$" , {'ha': 'center', 'va': 'center'}, rotation=90, bbox=dict(facecolor='white', alpha=0.8, edgecolor='black'))
- 创建一个包含垂直线所有值的容器会更容易,因为这些值将被重新用于放置线,并确定
axvspan
和 text
位置。在这种情况下,使用字典。
- 有关解释,请参阅内联符号
- 使用
.Axes.axvspan
在垂直位置之间填充
- How to highlight specific x-value ranges
- 见How do I merge two dictionaries in a single expression (take union of dictionaries)?
- 使用
.Axes.text
向图中添加文本
- 在
python 3.10
、matplotlib 3.5.1
中测试
# extra imports
from collections import OrderedDict
from itertools import zip_longest
np.random.seed(2022)
data = np.random.normal(loc=0.0, scale=1.0, size=2000)
df_data = pd.DataFrame(data)
def _plot(df):
for col in df.columns:
n_bins = 50
fig, axes = plt.subplots(figsize=(12,6))
n, bins, patches = axes.hist(df[col], n_bins, density=True, alpha=.1, edgecolor='black' )
mu = df[col].mean()
sigma = df[col].std()
pdf = 1/(sigma*np.sqrt(2*np.pi))*np.exp(-(bins-mu)**2/(2*sigma**2))
#probability density function
axes.plot(bins, pdf, color='green', alpha=.6)
# get ylim to position the text
y0, y1 = axes.get_ylim()
# create a dict for all the x values for vertical lines with the line color
muu = {mu: 'b'}
mm = {df_data[0].min(): 'r', df_data[0].max(): 'r'}
mun = {df_data[0].sub(v*sigma).mean(): 'b' for v in range(1, 4)}
mup = {df_data[0].add(v*sigma).mean(): 'b' for v in range(1, 4)}
# combine the dicts: | requires python 3.9+. See linked SO answer for additional opitons to combine the dicts
vals = muu | mm | mun | mup
# order the keys (x values) from smallest to largest
vals = OrderedDict(sorted(vals.items()))
# plot the dashed lines
for x, c in vals.items():
plt.axvline(x, color=c, linestyle='-.')
# combine the x values with colors of the stages
locs = list(zip_longest(vals.keys(), ['blue', 'brown']*4))
# iterate through all but the last value, and add the vspan and the text
for i, (x, c) in enumerate(locs[:-1]):
axes.axvspan(x, locs[i + 1][0], alpha=0.2, color=c)
tx = (x + locs[i + 1][0]) / 2
axes.text(tx, y1/2, f'Stage {i + 1}', {'ha': 'center', 'va': 'center'}, rotation=90)
plt.ylabel('Probability Density')
plt.xlabel('Values')
print(mu)
print(sigma)
_plot(df_data)
更新附加注释
# extra annotations
sign = [f'µ - {v}σ' for v in range(4, 0, -1)]
sigp = [f'µ + {v}σ' for v in range(1, 5)]
anno = sign + sigp
# iterate through all but the last value and add the vspan and the text
for i, (x, c) in enumerate(locs[:-1]):
axes.axvspan(x, locs[i + 1][0], alpha=0.2, color=c)
tx = (x + locs[i + 1][0]) / 2
axes.text(tx, y1/2, f'Stage {i + 1}: {anno[i]}', {'ha': 'center', 'va': 'center'}, rotation=90)
基于另一个
data = np.random.normal(loc=0.0, scale=1.0, size=2000)
df_data = pd.DataFrame(data)
import numpy as np
import scipy
import pandas as pd
from scipy.stats import norm
import matplotlib.pyplot as plt
def _plot(df):
for col in df.columns:
n_bins = 50
fig, axes = plt.subplots(figsize=(12,6))
n, bins, patches = axes.hist(df[col], n_bins, density=True, alpha=.1, edgecolor='black' )
mu = df[col].mean()
sigma = df[col].std()
pdf = 1/(sigma*np.sqrt(2*np.pi))*np.exp(-(bins-mu)**2/(2*sigma**2))
#probability density function
axes.plot(bins, pdf, color='green', alpha=.6)
#dashed lines
plt.axvline(np.mean(df_data[0]),color='b', linestyle='-.')
plt.axvline(np.mean(df_data[0]-sigma),color='b', linestyle='-.')
plt.axvline(np.mean(df_data[0]-2*sigma),color='b', linestyle='-.')
plt.axvline(np.mean(df_data[0]-3*sigma),color='b', linestyle='-.')
plt.axvline(min(df_data[0]),color='r', linestyle='-.')
plt.axvline(np.mean(df_data[0]+sigma),color='b', linestyle='-.')
plt.axvline(np.mean(df_data[0]+2*sigma),color='b', linestyle='-.')
plt.axvline(np.mean(df_data[0]+3*sigma),color='b', linestyle='-.')
plt.axvline(max(df_data[0]),color='r', linestyle='-.')
plt.ylabel('Probability Density')
plt.xlabel('Values')
print(mu)
print(sigma)
_plot(df_data)
哪个returns我这个好情节:
如您所见,蓝色垂直线表示由标准差的倍数设置的边界。我想添加以下信息和颜色编码,我现在将其快速放入 powerpoint 中:
我试图弄乱 plt.fill_between
函数,但没有真正得到任何有用的东西。我也不知道怎么写东西,比如这里的 mu+l*sigma,above plot。我怎样才能根据现有的获得第二张图片?
编辑: 由@Trenton McKinney
解决for i, (x, c) in enumerate(locs[:-1]):
axes.axvspan(x, locs[i + 1][0], alpha=0.2, color=c)
tx = (x + locs[i + 1][0]) / 2
axes.text(tx, y1/2, f'Zustand {i + 1}', {'ha': 'center', 'va': 'center'}, rotation=90)
if i<4:
axes.text(tx, y1/1.25, r"$\mu$" + "-" + f"{4-i}"+ "$\cdot$" + "$\sigma$" , {'ha': 'center', 'va': 'center'}, rotation=90, bbox=dict(facecolor='white', alpha=0.8, edgecolor='black'))
else:
axes.text(tx, y1/1.25, r"$\mu$" + "+" + f"{i-4 + 1}"+ "$\cdot$" + "$\sigma$" , {'ha': 'center', 'va': 'center'}, rotation=90, bbox=dict(facecolor='white', alpha=0.8, edgecolor='black'))
- 创建一个包含垂直线所有值的容器会更容易,因为这些值将被重新用于放置线,并确定
axvspan
和text
位置。在这种情况下,使用字典。 - 有关解释,请参阅内联符号
- 使用
.Axes.axvspan
在垂直位置之间填充- How to highlight specific x-value ranges
- 见How do I merge two dictionaries in a single expression (take union of dictionaries)?
- 使用
.Axes.text
向图中添加文本
- 在
python 3.10
、matplotlib 3.5.1
中测试
# extra imports
from collections import OrderedDict
from itertools import zip_longest
np.random.seed(2022)
data = np.random.normal(loc=0.0, scale=1.0, size=2000)
df_data = pd.DataFrame(data)
def _plot(df):
for col in df.columns:
n_bins = 50
fig, axes = plt.subplots(figsize=(12,6))
n, bins, patches = axes.hist(df[col], n_bins, density=True, alpha=.1, edgecolor='black' )
mu = df[col].mean()
sigma = df[col].std()
pdf = 1/(sigma*np.sqrt(2*np.pi))*np.exp(-(bins-mu)**2/(2*sigma**2))
#probability density function
axes.plot(bins, pdf, color='green', alpha=.6)
# get ylim to position the text
y0, y1 = axes.get_ylim()
# create a dict for all the x values for vertical lines with the line color
muu = {mu: 'b'}
mm = {df_data[0].min(): 'r', df_data[0].max(): 'r'}
mun = {df_data[0].sub(v*sigma).mean(): 'b' for v in range(1, 4)}
mup = {df_data[0].add(v*sigma).mean(): 'b' for v in range(1, 4)}
# combine the dicts: | requires python 3.9+. See linked SO answer for additional opitons to combine the dicts
vals = muu | mm | mun | mup
# order the keys (x values) from smallest to largest
vals = OrderedDict(sorted(vals.items()))
# plot the dashed lines
for x, c in vals.items():
plt.axvline(x, color=c, linestyle='-.')
# combine the x values with colors of the stages
locs = list(zip_longest(vals.keys(), ['blue', 'brown']*4))
# iterate through all but the last value, and add the vspan and the text
for i, (x, c) in enumerate(locs[:-1]):
axes.axvspan(x, locs[i + 1][0], alpha=0.2, color=c)
tx = (x + locs[i + 1][0]) / 2
axes.text(tx, y1/2, f'Stage {i + 1}', {'ha': 'center', 'va': 'center'}, rotation=90)
plt.ylabel('Probability Density')
plt.xlabel('Values')
print(mu)
print(sigma)
_plot(df_data)
更新附加注释
# extra annotations
sign = [f'µ - {v}σ' for v in range(4, 0, -1)]
sigp = [f'µ + {v}σ' for v in range(1, 5)]
anno = sign + sigp
# iterate through all but the last value and add the vspan and the text
for i, (x, c) in enumerate(locs[:-1]):
axes.axvspan(x, locs[i + 1][0], alpha=0.2, color=c)
tx = (x + locs[i + 1][0]) / 2
axes.text(tx, y1/2, f'Stage {i + 1}: {anno[i]}', {'ha': 'center', 'va': 'center'}, rotation=90)