龙空技术网

matplotlib的demo演示讲解,fill_between方法绘画直方图-亢保星

数说篮球 45

前言:

此时朋友们对“数据字典的画法”大体比较关切,我们都需要知道一些“数据字典的画法”的相关知识。那么小编也在网络上网罗了一些对于“数据字典的画法””的相关知识,希望姐妹们能喜欢,兄弟们快快来学习一下吧!

#!/usr/bin/env python#-*- coding:utf-8 -*-import itertoolsfrom functools import partialimport numpy as npimport matplotlib.pyplot as pltimport matplotlib.ticker as mtickerfrom cycler import cycler# set up histogram function to fixed bins"""阅读一:edges:边界,边缘的意思;这里是20个边界,范围是[-3,3],这个edges是一个等差数列。"""edges = np.linspace(-3, 3, 20, endpoint=True)"""partial 包装了np.histogram函数,给np.histogram规定一个默认参数bins,方便以后调用np.histogram:这方法的作用是: 计算一个数据集的分布。比如:有1,2,3,4,5,6这个数据集,经过np.histogram分析后,在1到3范围内有3个数字;在4到6范围内有3个数字。这个分析结果是基于bins=[1,3,6]的。"""hist_func = partial(np.histogram, bins=edges)# set up style cycles"""cycker: 是周期的意思cycler:是一个属性组合器,一个属性下面有多个值,可以有多个属性cycler:是一个迭代器,可以用迭代器的方式进行访问。cycle:cycle和cycle之间可以进行加法运算,组装成多个属性,每个属性下面有多个值。    它的数据结构如下:        颜色:蓝,黄,绿,红        标签:set 0 ,set 1,set 2,set 3        形状:形状0,形状1,形状2,形状3cycle: 它的访问,既可以按标签访问,这里的标签指的是(颜色,标签,形状),也可以    这样访问(蓝,set0,形状0),(黄,标签1,形状1);一组一组的的访问颜色属性,这个color_cycle里面有四种颜色,这里的facecolor是前景色的意思,我们从plt.rcParams['axes.prop_cycle'][:4]里面,拿四种前景色。[:4] 的意思是从0开始,取四个元素。我们的结果图里面有四种颜色,从下往上,依次是蓝色,黄色,绿色,红色"""color_cycle = cycler(facecolor=plt.rcParams['axes.prop_cycle'][:4])"""依然使用cycler这个数据结构,我们定义了四个标签,分别是set 0,set 1,set 2,set 3"""label_cycle = cycler(label=['set {n}'.format(n=n) for n in range(4)])"""形状周期(cycler):斜线,星装,方格,竖线"""hatch_cycle = cycler(hatch=['/', '*', '+', '|'])test_v = color_cycle+label_cycle+hatch_cyclefor v in test_v:    print(v)# Fixing random state for reproducibility"""设定随机种子,可以使程序每次运行,都产生同样的随机数。"""np.random.seed(19680801)"""应为我们有四个数据集的分布图,所以我们要做四组数据,放在stack_data中stack_data:是堆_数据的意思,我们这有四堆数据"""stack_data = np.random.randn(4, 12250)print(stack_data.shape)"""让四堆数据和四个label进行一一对应。这里的知识点有:(c['label'] for c in label_cycle):从label_cycle中获取lable周期对应的数据,获得的结果是一个元组("set 0","set 1","set 2","set 3")然后zip(元组,stack_data),形成一个zip对象,zip对象是一个迭代器,可以被迭代访问的。for...in 的形势进行访问。dict(zip),这个可以把一个zip对象转为字典"""dict_data = dict(zip((c['label'] for c in label_cycle), stack_data))for k,v in dict_data.items():    print(k)    print(v.shape)"""我们要做一个一行两列的图,figsize,宽950,高450,tight_layout:为True是紧密布局。"""fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(9, 4.5), tight_layout=True)"""调用我们的方法,先在第一个坐标系画图。我们传了四个参数,ax1坐标系;stack_data:要被我们统计分析的数据color_cycle+label_cycle+hatch_cycle,三个cycler相加,形成一个大的周期,这个大的周期数据结构如下:颜色:蓝,黄,绿,红标签:set 0 ,set 1,set 2,set 3形状:形状0,形状1,形状2,形状3hist_func: 从numpy来的统计函数,对stack_data中的数据进行统计分析"""arts = stack_hist(ax1, stack_data, color_cycle + label_cycle + hatch_cycle,                  hist_func=hist_func)arts = stack_hist(ax2, stack_data, color_cycle,                  hist_func=hist_func,                  plot_kwargs=dict(edgecolor='w', orientation='h'))"""设置x轴和y轴的标签。"""ax1.set_ylabel('counts')ax1.set_xlabel('x')ax2.set_xlabel('counts')ax2.set_ylabel('x')"""让这个图,绘画完成"""plt.show()"""阅读二:ax:直角坐标系stacked_data:被分析的数据sty_cycle:数据类型为cycler,是四种不同分布的形状,颜色,标签的设置。hist_func:数据分析函数,分析每个阶段,有多少个数据。"""def stack_hist(ax, stacked_data, sty_cycle, bottoms=None,               hist_func=None, labels=None,               plot_func=None, plot_kwargs=None):    """    Parameters    ----------    ax : axes.Axes        The axes to add artists too    stacked_data : array or Mapping        A (M, N) shaped array.  The first dimension will be iterated over to        compute histograms row-wise    sty_cycle : Cycler or operable of dict        Style to apply to each set    bottoms : array, default: 0        The initial positions of the bottoms.    hist_func : callable, optional        Must have signature `bin_vals, bin_edges = f(data)`.        `bin_edges` expected to be one longer than `bin_vals`    labels : list of str, optional        The label for each set.        If not given and stacked data is an array defaults to 'default set {n}'        If *stacked_data* is a mapping, and *labels* is None, default to the        keys.        If *stacked_data* is a mapping and *labels* is given then only the        columns listed will be plotted.    plot_func : callable, optional        Function to call to draw the histogram must have signature:          ret = plot_func(ax, edges, top, bottoms=bottoms,                          label=label, **kwargs)    plot_kwargs : dict, optional        Any extra keyword arguments to pass through to the plotting function.        This will be the same for all calls to the plotting function and will        override the values in *sty_cycle*.    Returns    -------    arts : dict        Dictionary of artists keyed on their labels    """    # deal with default binning(把...归入统计堆) function    """    我们传入了自己的hist_func,直方图分析函数。    所以不为None,代码不执行。    """    if hist_func is None:        hist_func = np.histogram    # deal with default plotting function    """    plot_func 画直方图的函数,我们没有传入画直方图的函数,    这里是None,我们用系统默认的直方图函数filled_hist.    我们在调用plot_func的时候,讲解这个函数。    """    if plot_func is None:        plot_func = filled_hist    # deal with default    """    我们没有设置plot_kwargs,也就是没有设置绘图的参数。这里直接为空。    """    if plot_kwargs is None:        plot_kwargs = {}    print(plot_kwargs)    try:        """        我们的stacked_data,也就是对数据是一个二维的数组,[4, 12250]        stack_data = np.random.randn(4, 12250)        哪里会有key?        调用stacked_data.keys(),肯定会抛出异常。直接跳到异常模块        """        l_keys = stacked_data.keys()        label_data = True        if labels is None:            labels = l_keys    #这里是异常模块    except AttributeError:        """        设置label_data = False,意思是没有标签数据。        """        label_data = False        if labels is None:            """            因为我们的labels为None,            itertools.repeat(None),这个方法返回的结果是一个迭代器            每次迭代的结果都是None.可以无限访问,访问就有,不访问就没有。            现在的labels是一个迭代器了。                        """            labels = itertools.repeat(None)    if label_data:        loop_iter = enumerate((stacked_data[lab], lab, s)                              for lab, s in zip(labels, sty_cycle))    else:        """        我们的label_data为False,就会执行下面这个代码。        zip 降三个数组装起来组装结果如下:        (我们要分析的第一个数据集,标签(这里为None),样式(颜色,形状,标签))        (我们要分析的第二个数据集,标签(这里为None),样式(颜色,形状,标签))        (我们要分析的第三个数据集,标签(这里为None),样式(颜色,形状,标签))        (我们要分析的第四个数据集,标签(这里为None),样式(颜色,形状,标签))        enumerate,枚举,enumerate给每速数据添加了一个索引。用for循环访问        可以返回这个索引。        """        loop_iter = enumerate(zip(stacked_data, labels, sty_cycle))    arts = {}    """    访问,我们封装的数据。    """    for j, (data, label, sty) in loop_iter:        """        我们的label为None,所以会执行if里面的语句,给当前label进行赋值。        """        if label is None:            label = 'dflt set {n}'.format(n=j)        """        这里的sty是一个字典,当用for循环访问sty_cycle的时候,sty_cycle是Cycler对象        也就是当用for循环访问Cycler对象的时候,它反会的是一个字典。        这个的sty的数据结构如下:        sty["lable"]=""        sty["hatch"]=""        syt["facecolor"]=""                pop是字典的方法,sty.pop('label', label)的意思是:        删除key为"label"的值,并返回这个key对应的值,        如果字典中没有这个key,就直接返回第二个参数对应的值。        """        label = sty.pop('label', label)        """        hist_fun开始对数据进行分析        edges 代表这个直方图中20条边。        vals 代表这个直方图中有19个柱子        """        vals, edges = hist_func(data)        if bottoms is None:            """            我们没有传入bottoms,也是柱状图的底部没有传入            默认为0.            我们要让这19根柱子,底部为0.就用            np.zeros_like(vals);这行代码的意思:            创建一个元素全是0的数组,这个数组的形状和vals的形状一样。            vals代表19根柱子的高度,也就是长度为19的数组            那么bottom就是19根柱子的底部位置            """            bottoms = np.zeros_like(vals)        """        bottoms 和 vals都是numpy的数组,可以用加法进行运算,        使两个数组对应的元素进行相加。        tips: python中普通数组的相加,只是将两个数组连接起来。        19根柱子的底部位置+19根柱子的高度,就算出了19根柱子的顶部位置        """        top = bottoms + vals        print(sty)        """        我们没有设置plot_kwargs,这里为None。        sty是一个字典。字典的update方法中,再传入一个字典,可以完成对原来字典的更新。        """        sty.update(plot_kwargs)        print(sty)        """        开始调用我们的绘图函数。        ax:直角坐标系。        edges:19根柱子的20个边。        top:19根柱子的高度所在位置        bottols:19根柱子的底部所在位置        label:19根柱子的标签。        **sty:对我们的样式字典进行解包:解包结果:color="",hatch=""        """        ret = plot_func(ax, edges, top, bottoms=bottoms,                        label=label, **sty)        """        第一个图画完了。第二个图,在第一个图的上边画。        所以第二个图的起点是第一个图的最高点。        """        bottoms = top        """        将绘图结果保存在字典里        """        arts[label] = ret    """    设置图例    """    ax.legend(fontsize=10)    return arts阅读三"""我们传入了参数ax:直角坐标系;edges:20条边values:19个柱子的顶部位置bottoms:19个柱子的底部位置**kwargs:参数:我们传入的样式。orientation:方向,我们没有传入,默认为v,垂直方向。"""def filled_hist(ax, edges, values, bottoms=None, orientation='v',                **kwargs):    """    Draw a histogram as a stepped patch.    Parameters    ----------    ax : Axes        The axes to plot to    edges : array        A length n+1 array giving the left edges of each bin and the        right edge of the last bin.    values : array        A length n array of bin counts or values    bottoms : float or array, optional        A length n array of the bottom of the bars.  If None, zero is used.    orientation : {'v', 'h'}       Orientation of the histogram.  'v' (default) has       the bars increasing in the positive y-direction.    **kwargs        Extra keyword arguments are passed through to `.fill_between`.    Returns    -------    ret : PolyCollection        Artist added to the Axes    """    """    传入的方向检查,要么是h,要么是v;其它的报错。    """    print(orientation)    if orientation not in 'hv':        raise ValueError("orientation must be in {{'h', 'v'}} "                         "not {o}".format(o=orientation))    """    如果kwargs中没有step,则设置step的值为post    如果kwargs中没有alpha,则设置alpha的值为0.7    """    kwargs.setdefault('step', 'post')    kwargs.setdefault('alpha', 0.7)    """    np.asarray: 将输入的数据转换为ndarray    """    edges = np.asarray(edges)    values = np.asarray(values)    """    如果19个柱子的边,不等于20,就报错。    """    if len(edges) - 1 != len(values):        raise ValueError('Must provide one more bin edge than value not: '                         'len(edges): {lb} len(values): {lv}'.format(            lb=len(edges), lv=len(values)))    """    如果bottoms为None,就默认为0,这个标量。标量是相对于向量来说的。    向量就是数组。    bottoms 也可以是数组。    我们给这个函数传入的bottoms就是一个数组。    """    if bottoms is None:        bottoms = 0    """    np.broadcast_to,这个函数的作用是:将bottoms中的值,广播到    values.shape中。    """    bottoms = np.broadcast_to(bottoms, values.shape)    """    在画图的时候,我们有20条边,我们要设置20条边的顶部位置    和20条边的底部位置。    现在values和bottoms里面存放的时候,19根柱子的顶部位置,19根柱子的底部位置    补充的这条边,应该和最后一条边一样长    """    values = np.append(values, values[-1])    bottoms = np.append(bottoms, bottoms[-1])    if orientation == 'h':        return ax.fill_betweenx(edges, values, bottoms,                                **kwargs)    elif orientation == 'v':        """        开始进行绘图        """        return ax.fill_between(edges, values, bottoms,                               **kwargs)    else:        raise AssertionError("you should never be here")

标签: #数据字典的画法