【问题标题】:How can the edge colors of individual matplotlib histograms be set?如何设置单个 matplotlib 直方图的边缘颜色?
【发布时间】:2017-09-25 17:55:15
【问题描述】:

我有一个粗略的现成函数,可用于使用直方图比较两组值:

我想在顶部图中设置每个直方图的单独边缘颜色(就像我如何设置用于每个直方图的单独值集一样)。这怎么可能?

import os

import datavision
import matplotlib.pyplot
import numpy
import shijian

def main():

    a = numpy.random.normal(2, 2, size = 120)
    b = numpy.random.normal(2, 2, size = 120)

    save_histogram_comparison_matplotlib(
        values_1      = a,
        values_2      = b,
        label_1       = "a",
        label_2       = "b",
        normalize     = True,
        label_ratio_x = "measurement",
        label_y       = "",
        title         = "comparison of a and b",
        filename      = "histogram_comparison_1.png"
    )

def save_histogram_comparison_matplotlib(
    values_1       = None,
    values_2       = None,
    filename       = None,
    directory      = ".",
    number_of_bins = None,
    normalize      = True,
    label_x        = "",
    label_y        = None,
    label_ratio_x  = None,
    label_ratio_y  = "ratio",
    title          = "comparison",
    label_1        = "1",
    label_2        = "2",
    overwrite      = True,
    LaTeX          = False,
    #aspect         = None,
    font_size      = 20,
    color_1        = "#3861AA",
    color_2        = "#00FF00",
    color_3        = "#7FDADC",
    color_edge_1   = "#3861AA", # |<---------- insert magic for these
    color_edge_2   = "#00FF00", # |
    alpha          = 0.5,
    width_line     = 1
    ):

    matplotlib.pyplot.ioff()
    if LaTeX is True:
        matplotlib.pyplot.rc("text", usetex = True)
        matplotlib.pyplot.rc("font", family = "serif")
    if number_of_bins is None:
        number_of_bins_1 = datavision.propose_number_of_bins(values_1)
        number_of_bins_2 = datavision.propose_number_of_bins(values_2)
        number_of_bins   = int((number_of_bins_1 + number_of_bins_2) / 2)
    if filename is None:
        if title is None:
            filename = "histogram_comparison.png"
        else:
            filename = shijian.propose_filename(
                filename  = title + ".png",
                overwrite = overwrite
            )
    else:
        filename = shijian.propose_filename(
            filename  = filename,
            overwrite = overwrite
        )

    values = []
    values.append(values_1)
    values.append(values_2)
    bar_width = 0.8
    figure, (axis_1, axis_2) = matplotlib.pyplot.subplots(
        nrows       = 2,
        gridspec_kw = {"height_ratios": (2, 1)}
    )
    ns, bins, patches = axis_1.hist(
        values,
        color     = [
                        color_1,
                        color_2
                    ],
        normed    = normalize,
        histtype  = "stepfilled",
        bins      = number_of_bins,
        alpha     = alpha,
        label     = [label_1, label_2],
        rwidth    = bar_width,
        linewidth = width_line,
        #edgecolor = [color_edge_1, color_edge_2] <---------- magic here? dunno
    )
    axis_1.legend(
        loc = "best"
    )
    bars = axis_2.bar(
        bins[:-1],
        ns[0] / ns[1],
        alpha     = 1,
        linewidth = 0, #width_line
        width     = bins[1] - bins[0]
    )
    for bar in bars:
        bar.set_color(color_3)
    axis_1.set_xlabel(label_x, fontsize = font_size)
    axis_1.set_ylabel(label_y, fontsize = font_size)
    axis_2.set_xlabel(label_ratio_x, fontsize = font_size)
    axis_2.set_ylabel(label_ratio_y, fontsize = font_size)
    #axis_1.xticks(fontsize = font_size)
    #axis_1.yticks(fontsize = font_size)
    #axis_2.xticks(fontsize = font_size)
    #axis_2.yticks(fontsize = font_size)
    matplotlib.pyplot.suptitle(title, fontsize = font_size)
    if not os.path.exists(directory):
        os.makedirs(directory)
    #if aspect is None:
    #    matplotlib.pyplot.axes().set_aspect(
    #        1 / matplotlib.pyplot.axes().get_data_ratio()
    #    )
    #else:
    #    matplotlib.pyplot.axes().set_aspect(aspect)
    figure.tight_layout()
    matplotlib.pyplot.subplots_adjust(top = 0.9)
    matplotlib.pyplot.savefig(
        directory + "/" + filename,
        dpi = 700
    )
    matplotlib.pyplot.close()

if __name__ == "__main__":
    main()

【问题讨论】:

    标签: matplotlib colors histogram


    【解决方案1】:

    您可以简单地绘制两个不同的直方图,但共享 bin。

    import numpy as np; np.random.seed(3)
    import matplotlib.pyplot as plt
    
    a = np.random.normal(size=(89,2))
    
    kws = dict(histtype= "stepfilled",alpha= 0.5, linewidth = 2)
    hist, edges,_ = plt.hist(a[:,0], bins = 6,color="lightseagreen", label = "A", edgecolor="k", **kws)
    plt.hist(a[:,1], bins = edges,color="gold", label = "B",  edgecolor="crimson", **kws)
    
    plt.show()
    

    【讨论】:

      【解决方案2】:

      使用hist() 函数返回的Patches 对象列表。

      在您的情况下,您有两个数据集,因此您的变量 patches 将是一个包含两个列表的列表,每个列表都有 Patches 用于在绘图上绘制条形的对象。

      您可以使用setp() 函数轻松设置所有这些对象的属性。例如:

      a = np.random.normal(size=(100,))
      b = np.random.normal(size=(100,))
      c,d,e = plt.hist([a,b], color=['r','g'])
      plt.setp(e[0], edgecolor='k', lw=2)
      plt.setp(e[1], edgecolor='b', lw=3)
      

      【讨论】:

        猜你喜欢
        • 2019-03-08
        • 1970-01-01
        • 2011-02-08
        • 2018-02-15
        • 1970-01-01
        • 2013-09-16
        • 2017-06-29
        • 2017-11-27
        • 2013-12-06
        相关资源
        最近更新 更多