コード例 #1
0
ファイル: matplotlib.py プロジェクト: lkorley/physti
def line(h1: Union[Histogram1D, "HistogramCollection"],
         ax: Axes,
         *,
         errors: bool = False,
         **kwargs):
    """Line plot of 1D histogram."""

    show_stats = kwargs.pop("show_stats", False)
    show_values = kwargs.pop("show_values", False)
    density = kwargs.pop("density", False)
    cumulative = kwargs.pop("cumulative", False)
    value_format = kwargs.pop("value_format", None)
    text_kwargs = pop_kwargs_with_prefix("text_", kwargs)
    kwargs["label"] = kwargs.get("label", h1.name)

    data = get_data(h1, cumulative=cumulative, density=density)
    _apply_xy_lims(ax, h1, data, kwargs)
    _add_ticks(ax, h1, kwargs)
    _add_labels(ax, h1, kwargs)

    if errors:
        err_data = get_err_data(h1, cumulative=cumulative, density=density)
        ax.errorbar(h1.bin_centers,
                    data,
                    yerr=err_data,
                    fmt=kwargs.pop("fmt", "-"),
                    ecolor=kwargs.pop("ecolor", "black"),
                    **kwargs)
    else:
        ax.plot(h1.bin_centers, data, **kwargs)

    if show_stats:
        _add_stats_box(h1, ax, stats=show_stats)
    if show_values:
        _add_values(ax, h1, data, value_format=value_format, **text_kwargs)
コード例 #2
0
ファイル: matplotlib.py プロジェクト: lkorley/physti
def polar_map(hist: Histogram2D,
              ax: Axes,
              *,
              show_zero: bool = True,
              show_colorbar: bool = True,
              **kwargs):
    """Polar map of polar histograms.

    Similar to map, but supports less parameters."""
    data = get_data(hist,
                    cumulative=False,
                    flatten=True,
                    density=kwargs.pop("density", False))

    cmap = _get_cmap(kwargs)
    norm, cmap_data = _get_cmap_data(data, kwargs)
    colors = cmap(cmap_data)

    rpos, phipos = (arr.flatten() for arr in hist.get_bin_left_edges())
    dr, dphi = (arr.flatten() for arr in hist.get_bin_widths())
    rmax, _ = (arr.flatten() for arr in hist.get_bin_right_edges())

    bar_args = {}
    if "zorder" in kwargs:
        bar_args["zorder"] = kwargs.pop("zorder")

    alphas = _get_alpha_data(cmap_data, kwargs)
    if np.isscalar(alphas):
        alphas = np.ones_like(data) * alphas

    for i in range(len(rpos)):
        if data[i] > 0 or show_zero:
            bin_color = colors[i]
            # TODO: align = "edge"
            bars = ax.bar(phipos[i],
                          dr[i],
                          width=dphi[i],
                          bottom=rpos[i],
                          align='edge',
                          color=bin_color,
                          edgecolor=kwargs.get("grid_color", cmap(0.5)),
                          lw=kwargs.get("lw", 0.5),
                          alpha=alphas[i],
                          **bar_args)

    ax.set_rmax(rmax.max())
    if show_colorbar:
        _add_colorbar(ax, cmap, cmap_data, norm)
コード例 #3
0
ファイル: matplotlib.py プロジェクト: lkorley/physti
def cylinder_map(hist: Union[Histogram2D, CylinderSurfaceHistogram],
                 ax: Axes3D,
                 *,
                 show_zero: bool = True,
                 **kwargs):
    """Heat map plotted on the surface of a cylinder."""
    data = get_data(hist,
                    cumulative=False,
                    flatten=False,
                    density=kwargs.pop("density", False))

    cmap = _get_cmap(kwargs)
    norm, cmap_data = _get_cmap_data(data, kwargs)
    colors = cmap(cmap_data)

    if hasattr(hist, "radius"):
        r = kwargs.pop("radius", hist.radius)
    else:
        r = kwargs.pop("radius", 1)

    xs = r * np.outer(np.cos(hist.numpy_bins[0]), np.ones(hist.shape[1] + 1))
    ys = r * np.outer(np.sin(hist.numpy_bins[0]), np.ones(hist.shape[1] + 1))
    zs = np.outer(np.ones(hist.shape[0] + 1), hist.numpy_bins[1])

    for i in range(hist.shape[0]):
        for j in range(hist.shape[1]):
            if not show_zero and not data[i, j]:
                continue
            x = xs[i, j], xs[i, j + 1], xs[i + 1, j + 1], xs[i + 1, j]
            y = ys[i, j], ys[i, j + 1], ys[i + 1, j + 1], ys[i + 1, j]
            z = zs[i, j], zs[i, j + 1], zs[i + 1, j + 1], zs[i + 1, j]
            verts = [list(zip(x, y, z))]
            col = Poly3DCollection(verts)
            col.set_facecolor(colors[i, j])
            ax.add_collection3d(col)

    ax.set_xlabel("x")
    ax.set_ylabel("y")
    ax.set_zlabel("z")

    if matplotlib.__version__ < "2":
        ax.plot_surface([], [], [], color="b")
    ax.set_xlim(-r * 1.1, r * 1.1)
    ax.set_ylim(-r * 1.1, r * 1.1)
    ax.set_zlim(zs.min(), zs.max())
コード例 #4
0
ファイル: matplotlib.py プロジェクト: lkorley/physti
def globe_map(hist: Union[Histogram2D, DirectionalHistogram],
              ax: Axes3D,
              *,
              show_zero: bool = True,
              **kwargs):
    """Heat map plotted on the surface of a sphere."""
    data = get_data(hist,
                    cumulative=False,
                    flatten=False,
                    density=kwargs.pop("density", False))

    cmap = _get_cmap(kwargs)
    norm, cmap_data = _get_cmap_data(data, kwargs)
    colors = cmap(cmap_data)
    lw = kwargs.pop("lw", 1)

    r = 1
    xs = r * np.outer(np.sin(hist.numpy_bins[0]), np.cos(hist.numpy_bins[1]))
    ys = r * np.outer(np.sin(hist.numpy_bins[0]), np.sin(hist.numpy_bins[1]))
    zs = r * np.outer(np.cos(hist.numpy_bins[0]), np.ones(hist.shape[1] + 1))

    for i in range(hist.shape[0]):
        for j in range(hist.shape[1]):
            if not show_zero and not data[i, j]:
                continue
            x = xs[i, j], xs[i, j + 1], xs[i + 1, j + 1], xs[i + 1, j]
            y = ys[i, j], ys[i, j + 1], ys[i + 1, j + 1], ys[i + 1, j]
            z = zs[i, j], zs[i, j + 1], zs[i + 1, j + 1], zs[i + 1, j]
            verts = [list(zip(x, y, z))]
            col = Poly3DCollection(verts)
            col.set_facecolor(colors[i, j])
            col.set_edgecolor("black")
            col.set_linewidth(lw)
            ax.add_collection3d(col)

    ax.set_xlabel("x")
    ax.set_ylabel("y")
    ax.set_zlabel("z")

    if matplotlib.__version__ < "2":
        ax.plot_surface([], [], [], color="b")
    ax.set_xlim(-1.1, 1.1)
    ax.set_ylim(-1.1, 1.1)
    ax.set_zlim(-1.1, 1.1)
    return ax
コード例 #5
0
ファイル: matplotlib.py プロジェクト: lkorley/physti
def image(h2: Histogram2D,
          ax: Axes,
          *,
          show_colorbar: bool = True,
          interpolation: str = "nearest",
          **kwargs):
    """Plot of 2D histograms based on pixmaps.

    Similar to map, but it:
    - has fewer options
    - is much more effective (enables thousands)
    - does not support irregular bins

    Parameters
    ----------
    interpolation: interpolation parameter passed to imshow, default: "nearest" (creates rectangles)
    """
    cmap = _get_cmap(kwargs)  # h2 as well?
    data = get_data(h2, cumulative=False, density=kwargs.pop("density", False))
    norm, cmap_data = _get_cmap_data(data, kwargs)
    # zorder = kwargs.pop("zorder", None)

    for binning in h2._binnings:
        if not binning.is_regular():
            raise RuntimeError(
                "Histograms with irregular bins cannot be plotted using image method."
            )

    kwargs["interpolation"] = interpolation
    if kwargs.get("xscale") == "log" or kwargs.get("yscale") == "log":
        raise RuntimeError("Cannot use logarithmic axes with image plots.")

    _apply_xy_lims(ax, h2, data=data, kwargs=kwargs)

    _add_labels(ax, h2, kwargs)
    ax.imshow(data.T[::-1, :],
              cmap=cmap,
              norm=norm,
              extent=(h2.bins[0][0, 0], h2.bins[0][-1, 1], h2.bins[1][0, 0],
                      h2.bins[1][-1, 1]),
              aspect="auto",
              **kwargs)

    if show_colorbar:
        _add_colorbar(ax, cmap, cmap_data, norm)
コード例 #6
0
ファイル: matplotlib.py プロジェクト: lkorley/physti
def bar3d(h2: Histogram2D, ax: Axes3D, **kwargs):
    """Plot of 2D histograms as 3D boxes."""
    density = kwargs.pop("density", False)
    data = get_data(h2, cumulative=False, flatten=True, density=density)

    if "cmap" in kwargs:
        cmap = _get_cmap(kwargs)
        _, cmap_data = _get_cmap_data(data, kwargs)
        colors = cmap(cmap_data)
    else:
        colors = kwargs.pop("color", kwargs.pop("c", "blue"))

    xpos, ypos = (arr.flatten() for arr in h2.get_bin_centers())
    zpos = np.zeros_like(ypos)
    dx, dy = (arr.flatten() for arr in h2.get_bin_widths())

    _add_labels(ax, h2, kwargs)
    ax.bar3d(xpos, ypos, zpos, dx, dy, data, color=colors, **kwargs)
    ax.set_zlabel("density" if density else "frequency")
コード例 #7
0
ファイル: matplotlib.py プロジェクト: lkorley/physti
def bar(h1: Histogram1D, ax: Axes, *, errors: bool = False, **kwargs):
    """Bar plot of 1D histograms."""
    show_stats = kwargs.pop("show_stats", False)
    show_values = kwargs.pop("show_values", False)
    value_format = kwargs.pop("value_format", None)
    density = kwargs.pop("density", False)
    cumulative = kwargs.pop("cumulative", False)
    label = kwargs.pop("label", h1.name)
    lw = kwargs.pop("linewidth", kwargs.pop("lw", 0.5))
    text_kwargs = pop_kwargs_with_prefix("text_", kwargs)

    data = get_data(h1, cumulative=cumulative, density=density)

    if "cmap" in kwargs:
        cmap = _get_cmap(kwargs)
        _, cmap_data = _get_cmap_data(data, kwargs)
        colors = cmap(cmap_data)
    else:
        colors = kwargs.pop("color", kwargs.pop("c", None))

    _apply_xy_lims(ax, h1, data, kwargs)
    _add_ticks(ax, h1, kwargs)

    if errors:
        err_data = get_err_data(h1, cumulative=cumulative, density=density)
        kwargs["yerr"] = err_data
        if "ecolor" not in kwargs:
            kwargs["ecolor"] = "black"

    _add_labels(ax, h1, kwargs)
    ax.bar(h1.bin_left_edges,
           data,
           h1.bin_widths,
           align="edge",
           label=label,
           color=colors,
           linewidth=lw,
           **kwargs)

    if show_values:
        _add_values(ax, h1, data, value_format=value_format, **text_kwargs)
    if show_stats:
        _add_stats_box(h1, ax, stats=show_stats)
コード例 #8
0
ファイル: matplotlib.py プロジェクト: lkorley/physti
def fill(h1: Histogram1D, ax: Axes, **kwargs):
    """Fill plot of 1D histogram."""
    show_stats = kwargs.pop("show_stats", False)
    # show_values = kwargs.pop("show_values", False)
    density = kwargs.pop("density", False)
    cumulative = kwargs.pop("cumulative", False)
    kwargs["label"] = kwargs.get("label", h1.name)

    data = get_data(h1, cumulative=cumulative, density=density)
    _apply_xy_lims(ax, h1, data, kwargs)
    _add_ticks(ax, h1, kwargs)
    _add_labels(ax, h1, kwargs)

    ax.fill_between(h1.bin_centers, 0, data, **kwargs)

    if show_stats:
        _add_stats_box(h1, ax, stats=show_stats)
    # if show_values:
    #     _add_values(ax, h1, data)
    return ax
コード例 #9
0
ファイル: matplotlib.py プロジェクト: lkorley/physti
def step(h1: Histogram1D, ax: Axes, **kwargs):
    """Step line-plot of 1D histogram."""
    show_stats = kwargs.pop("show_stats", False)
    show_values = kwargs.pop("show_values", False)
    density = kwargs.pop("density", False)
    cumulative = kwargs.pop("cumulative", False)
    value_format = kwargs.pop("value_format", None)
    text_kwargs = pop_kwargs_with_prefix("text_", kwargs)
    kwargs["label"] = kwargs.get("label", h1.name)

    data = get_data(h1, cumulative=cumulative, density=density)
    _apply_xy_lims(ax, h1, data, kwargs)
    _add_ticks(ax, h1, kwargs)
    _add_labels(ax, h1, kwargs)

    ax.step(h1.numpy_bins, np.concatenate([data[:1], data]), **kwargs)

    if show_stats:
        _add_stats_box(h1, ax, stats=show_stats)
    if show_values:
        _add_values(ax, h1, data, value_format=value_format, **text_kwargs)
コード例 #10
0
ファイル: matplotlib.py プロジェクト: lkorley/physti
def scatter(h1: Histogram1D, ax: Axes, *, errors: bool = False, **kwargs):
    """Scatter plot of 1D histogram."""
    show_stats = kwargs.pop("show_stats", False)
    show_values = kwargs.pop("show_values", False)
    density = kwargs.pop("density", False)
    cumulative = kwargs.pop("cumulative", False)
    value_format = kwargs.pop("value_format", None)
    text_kwargs = pop_kwargs_with_prefix("text_", kwargs)
    label = kwargs.pop("label", h1.name)

    data = get_data(h1, cumulative=cumulative, density=density)

    if "cmap" in kwargs:
        cmap = _get_cmap(kwargs)
        _, cmap_data = _get_cmap_data(data, kwargs)
        kwargs["color"] = cmap(cmap_data)
    elif "color" in kwargs or "c" in kwargs:
        kwargs["color"] = kwargs.pop("color", kwargs.get("c", None))

    _apply_xy_lims(ax, h1, data, kwargs)
    _add_ticks(ax, h1, kwargs)
    _add_labels(ax, h1, kwargs)

    if errors:
        err_data = get_err_data(h1, cumulative=cumulative, density=density)
        ax.errorbar(h1.bin_centers,
                    data,
                    yerr=err_data,
                    fmt=kwargs.pop("fmt", "o"),
                    ecolor=kwargs.pop("ecolor", "black"),
                    ms=0)
    ax.scatter(h1.bin_centers, data, label=label, **kwargs)

    if show_values:
        _add_values(ax, h1, data, value_format=value_format, **text_kwargs)
    if show_stats:
        _add_stats_box(h1, ax, stats=show_stats)
コード例 #11
0
ファイル: matplotlib.py プロジェクト: lkorley/physti
def surface_map(hist,
                ax: Axes3D,
                *,
                show_zero: bool = True,
                x=(lambda x, y: x),
                y=(lambda x, y: y),
                z=(lambda x, y: 0),
                **kwargs):
    """Coloured-rectangle plot of 2D histogram, placed on an arbitrary surface.

    Each bin is mapped to a rectangle in 3D space using the x,y,z functions.

    Parameters
    ----------
    hist : Histogram2D
    show_zero : Optional[bool]
        Whether to show coloured box for bins with 0 frequency (otherwise background).
    x : function
        Function with 2 parameters used to map bins to spatial x coordinate
    y : function
        Function with 2 parameters used to map bins to spatial y coordinate
    z : function
        Function with 2 parameters used to map bins to spatial z coordinate

    Returns
    -------
    matplotlib.axes._subplots.Axes3DSubplot

    See Also
    --------
    map, cylinder_map, globe_map
    """
    data = get_data(hist,
                    cumulative=False,
                    flatten=False,
                    density=kwargs.pop("density", False))

    cmap = _get_cmap(kwargs)
    norm, cmap_data = _get_cmap_data(data, kwargs)
    colors = cmap(cmap_data)

    xs = np.ndarray((hist.shape[0] + 1, hist.shape[1] + 1), dtype=float)
    ys = np.ndarray((hist.shape[0] + 1, hist.shape[1] + 1), dtype=float)
    zs = np.ndarray((hist.shape[0] + 1, hist.shape[1] + 1), dtype=float)

    edges_x = hist.numpy_bins[0]
    edges_y = hist.numpy_bins[1]

    for i in range(hist.shape[0] + 1):
        for j in range(hist.shape[1] + 1):
            xs[i, j] = x(edges_x[i], edges_y[j])
            ys[i, j] = y(edges_x[i], edges_y[j])
            zs[i, j] = z(edges_x[i], edges_y[j])

    for i in range(hist.shape[0]):
        for j in range(hist.shape[1]):
            if not show_zero and not data[i, j]:
                continue
            x = xs[i, j], xs[i, j + 1], xs[i + 1, j + 1], xs[i + 1, j]
            y = ys[i, j], ys[i, j + 1], ys[i + 1, j + 1], ys[i + 1, j]
            z = zs[i, j], zs[i, j + 1], zs[i + 1, j + 1], zs[i + 1, j]
            verts = [list(zip(x, y, z))]
            col = Poly3DCollection(verts)
            col.set_facecolor(colors[i, j])
            ax.add_collection3d(col)

    ax.set_xlabel("x")
    ax.set_ylabel("y")
    ax.set_zlabel("z")

    if matplotlib.__version__ < "2":
        ax.plot_surface([], [], [], color="b")  # Dummy plot
    ax.set_xlim(xs.min(), xs.max())
    ax.set_ylim(ys.min(), ys.max())
    ax.set_zlim(zs.min(), zs.max())

    # ax.plot_surface(x, y, z, rstride=hist.shape[0], color="b")

    return ax
コード例 #12
0
ファイル: matplotlib.py プロジェクト: lkorley/physti
def map(h2: Histogram2D,
        ax: Axes,
        *,
        show_zero: bool = True,
        show_values: bool = False,
        show_colorbar: bool = True,
        x=None,
        y=None,
        **kwargs):
    """Coloured-rectangle plot of 2D histogram.

    Parameters
    ----------
    show_zero : Whether to show coloured box for bins with 0 frequency (otherwise background).
    show_values : Whether to show labels with frequencies/densities in the middle of the bin


    text_color : Optional
        Colour of text descriptions
    text_alpha : Optional[float]
        Alpha for the text labels only
    x : Optional[Callable]
        Transformation of x bin coordinates
    y : Optional[Callable]
        Transformation of y bin coordinates
    zorder : float
        z-order in the axis (higher number above lower)

    See Also
    --------
    image, polar_map, surface_map

    Notes
    -----
    If you transform axes using x or y parameters, the deduction of axis limits
    does not work well automatically. Please, make sure to attend to it yourself.
    The densities in transformed maps are calculated from original bins.
    """
    # Detect transformation
    transformed = False
    if x is not None or y is not None:
        if not x:
            x = lambda x, y: x
        if not y:
            y = lambda x, y: y
        transformed = True

    value_format = kwargs.pop("value_format", lambda x: str(x))
    # TODO: Implement correctly the text_kwargs

    if isinstance(value_format, str):
        format_str = "{0:" + value_format + "}"
        value_format = lambda x: format_str.format(x)

    rect_args = {}
    if "zorder" in kwargs:
        rect_args["zorder"] = kwargs.pop("zorder")

    data = get_data(h2,
                    cumulative=False,
                    flatten=True,
                    density=kwargs.pop("density", False))

    cmap = _get_cmap(kwargs)
    norm, cmap_data = _get_cmap_data(data, kwargs)
    colors = cmap(cmap_data)

    xpos, ypos = (arr.flatten() for arr in h2.get_bin_left_edges())
    dx, dy = (arr.flatten() for arr in h2.get_bin_widths())
    text_x, text_y = (arr.flatten() for arr in h2.get_bin_centers())

    _apply_xy_lims(ax, h2, data=data, kwargs=kwargs)
    _add_labels(ax, h2, kwargs)

    ax.autoscale_view()

    alphas = _get_alpha_data(cmap_data, kwargs)
    if np.isscalar(alphas):
        alphas = np.ones_like(data) * alphas

    for i in range(len(xpos)):
        bin_color = colors[i]
        alpha = alphas[i]

        if data[i] != 0 or show_zero:
            if not transformed:
                rect = plt.Rectangle([xpos[i], ypos[i]],
                                     dx[i],
                                     dy[i],
                                     facecolor=bin_color,
                                     edgecolor=kwargs.get(
                                         "grid_color", cmap(0.5)),
                                     lw=kwargs.get("lw", 0.5),
                                     alpha=alpha,
                                     **rect_args)
                tx, ty = text_x[i], text_y[i]

            else:
                # See http://matplotlib.org/users/path_tutorial.html
                points = ((xpos[i], ypos[i]), (xpos[i] + dx[i], ypos[i]),
                          (xpos[i] + dx[i], ypos[i] + dy[i]),
                          (xpos[i], ypos[i] + dy[i]), (xpos[i], ypos[i]))

                verts = [(x(*p), y(*p)) for p in points]

                codes = [
                    path.Path.MOVETO,
                    path.Path.LINETO,
                    path.Path.LINETO,
                    path.Path.LINETO,
                    path.Path.CLOSEPOLY,
                ]

                rect_path = path.Path(verts, codes)
                rect = patches.PathPatch(rect_path,
                                         facecolor=bin_color,
                                         edgecolor=kwargs.get(
                                             "grid_color", cmap(0.5)),
                                         lw=kwargs.get("lw", 0.5),
                                         alpha=alpha,
                                         **rect_args)

                tx = x(text_x[i], text_y[i])
                ty = y(text_x[i], text_y[i])
            ax.add_patch(rect)

            if show_values:
                text = value_format(data[i])
                yiq_y = np.dot(bin_color[:3], [0.299, 0.587, 0.114])

                text_color = kwargs.get("text_color", None)
                if not text_color:
                    if yiq_y > 0.5:
                        text_color = (0.0, 0.0, 0.0,
                                      kwargs.get("text_alpha", alpha))
                    else:
                        text_color = (1.0, 1.0, 1.0,
                                      kwargs.get("text_alpha", alpha))
                ax.text(tx,
                        ty,
                        text,
                        horizontalalignment='center',
                        verticalalignment='center',
                        color=text_color,
                        clip_on=True,
                        **rect_args)

    if show_colorbar:
        _add_colorbar(ax, cmap, cmap_data, norm)