绘制文本框并填充Matplotlib Python中垂直线之间的颜色

发布于 2025-01-26 04:53:45 字数 3114 浏览 3 评论 0原文

based on another 线程我得到了此代码:

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)

它返回了我这个不错的情节:

您可以看到蓝色垂直线表示由标准偏差的倍数设置的边界。我想添加以下信息和颜色编码,现在我很快将其放置在PowerPoint:

“ https://i.sstatic.net/formj.png” alt =“在此处输入图像说明”>

我尝试与plt.fill_between函数混乱有用。我也不知道如何写东西,例如Mu+l*Sigma,上面的 。我该如何根据自己的目标来实现第二张图片?

编辑: 由@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'))

based on another thread i got this code:

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)

Which returns me this nice plot:
enter image description here

As you can see the blue vertical lines indicate borders set by multiples of standard deviations. I would like to add the following information and color coding, which I now quickly placed in powerpoint:

enter image description here

I tried to mess with the plt.fill_between function but didnt really get anything useful. Also I do not know how to write something, like the mu+l*sigma here, above the plot. How can i achieve the second picture based on what I have?

EDIT:
solved by @Trenton McKinney

enter image description here
Putting new boxes inside the colored boxes:

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
quot; + "-" + f"{4-i}"+ "$\cdot
quot; + "$\sigma
quot; , {'ha': 'center', 'va': 'center'}, rotation=90, bbox=dict(facecolor='white', alpha=0.8, edgecolor='black'))
            else:
                axes.text(tx, y1/1.25, r"$\mu
quot; + "+" + f"{i-4 + 1}"+ "$\cdot
quot; + "$\sigma
quot; , {'ha': 'center', 'va': 'center'}, rotation=90, bbox=dict(facecolor='white', alpha=0.8, edgecolor='black'))

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

面犯桃花 2025-02-02 04:53:45
# 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)

< img src =“ https://i.sstatic.net/bsx2m.png” alt =“在此处输入图像说明”>

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

enter image description here

Update for additional annotations

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

enter image description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文