예제 #1
0
def validate_and_transform_options(series: MultiSeries,
                                   kwargs: Dict = {}) -> Options:
    """
    This will check the keyword arguments passed to the `uniplot.plot` function, will transform them and will return them in form of an `Options` object.
    """
    # Set bounds to show all points by default
    kwargs["x_min"] = kwargs.get("x_min") or series.x_min()
    kwargs["x_max"] = kwargs.get("x_max") or (
        series.x_max() + 1e-4 * (series.x_max() - series.x_min()))
    if float(kwargs["x_min"]) == float(kwargs["x_max"]):
        kwargs["x_min"] = kwargs["x_min"] - 1
        kwargs["x_max"] = kwargs["x_max"] + 1
    kwargs["y_min"] = kwargs.get("y_min") or series.y_min()
    kwargs["y_max"] = kwargs.get("y_max") or (
        series.y_max() + 1e-4 * (series.y_max() - series.y_min()))
    if float(kwargs["y_min"]) == float(kwargs["y_max"]):
        kwargs["y_min"] = kwargs["y_min"] - 1
        kwargs["y_max"] = kwargs["y_max"] + 1

    # Make sure the length of the labels is not exceeding the number of series
    if kwargs.get("legend_labels") is not None:
        kwargs["legend_labels"] = list(kwargs["legend_labels"])[0:len(series)]

    if "color" not in kwargs:
        kwargs["color"] = len(series) > 1

    return Options(**kwargs)
예제 #2
0
def validate_and_transform_options(series: MultiSeries,
                                   kwargs: Dict = {}) -> Options:
    """
    This will check the keyword arguments passed to the `uniplot.plot` function, will transform them and will return them in form of an `Options` object.

    The idea is to cast arguments into the right format to be used by the rest of the library, and to be as tolerant as possible for ease of use of the library.

    As a result the somewhat hacky code below should at least be confined to this function, and not spread throughout uniplot.
    """
    # Set x bounds to show all points by default
    x_enlarge_delta = AUTO_WINDOW_ENLARGE_FACTOR * (series.x_max() -
                                                    series.x_min())
    kwargs["x_min"] = kwargs.get("x_min", series.x_min() - x_enlarge_delta)
    kwargs["x_max"] = kwargs.get("x_max", series.x_max() + x_enlarge_delta)

    # Fallback for only a single data point, or multiple with single x coordinate
    if float(kwargs["x_min"]) == float(kwargs["x_max"]):
        kwargs["x_min"] = kwargs["x_min"] - 1
        kwargs["x_max"] = kwargs["x_max"] + 1

    # Set y bounds to show all points by default
    y_enlarge_delta = AUTO_WINDOW_ENLARGE_FACTOR * (series.y_max() -
                                                    series.y_min())
    kwargs["y_min"] = kwargs.get("y_min", series.y_min() - y_enlarge_delta)
    kwargs["y_max"] = kwargs.get("y_max", series.y_max() + y_enlarge_delta)

    # Fallback for only a single data point, or multiple with single y coordinate
    if float(kwargs["y_min"]) == float(kwargs["y_max"]):
        kwargs["y_min"] = kwargs["y_min"] - 1
        kwargs["y_max"] = kwargs["y_max"] + 1

    # Make sure the length of the labels is not exceeding the number of series
    if kwargs.get("legend_labels") is not None:
        kwargs["legend_labels"] = list(kwargs["legend_labels"])[0:len(series)]

    # By default, enable color for multiple series, disable color for a single one
    kwargs["color"] = kwargs.get("color", len(series) > 1)

    # Set lines option for all series
    if not kwargs.get("lines"):
        # This will work for both unset lines option and `False`
        kwargs["lines"] = [False] * len(series)
    elif kwargs.get("lines") is True:
        # This is used to expand a single `True`
        kwargs["lines"] = [True] * len(series)
    elif len(kwargs.get("lines")) != len(series):  # type: ignore
        raise ValueError("Invalid 'lines' option.")

    return Options(**kwargs)
예제 #3
0
def test_min_and_max():
    ys = [[1, 222, 3, -3.14, 0], [1, 222, 3, -3.14, 0]]
    xs = [[1000, 222, 3, -314, 0], [0, 2222, 3, -3.14, 0]]
    series = MultiSeries(xs=xs, ys=ys)

    assert series.x_min() == -314
    assert series.x_max() == 2222
    assert series.y_min() == -3.14
    assert series.y_max() == 222
예제 #4
0
def histogram(
    xs: Any,
    bins: int = 20,
    bins_min: Optional[float] = None,
    bins_max: Optional[float] = None,
    **kwargs,
) -> None:
    """
    Plot a histogram to the terminal.

    Parameters:

    - `xs` are the values of the points to plot. This parameter is mandatory and
      can either be a list or a list of lists, or the equivalent NumPy array.
    - Any additional keyword arguments are passed to the `uniplot.options.Options` class.
    """
    # HACK Use the `MultiSeries` constructor to cast values to uniform format
    multi_series = MultiSeries(ys=xs)

    # Histograms usually make sense only with lines
    kwargs["lines"] = kwargs.get("lines", True)

    bins_min = bins_min or multi_series.y_min()
    bins_max = bins_max or multi_series.y_max()
    range = bins_max - bins_min
    if range > 0:
        bins_min = bins_min - 0.1 * range
        bins_max = bins_max + 0.1 * range

    xs_histo_series = []
    ys_histo_series = []
    for s in multi_series.ys:
        hist, bin_edges = np.histogram(s,
                                       bins=bins,
                                       range=(bins_min, bins_max))

        # Draw vertical and horizontal lines to connect points
        xs_here = np.zeros(1 + 2 * bins + 1)
        ys_here = np.zeros(1 + 2 * bins + 1)
        xs_here[0] = bin_edges[0]
        xs_here[1::2] = bin_edges
        xs_here[2::2] = bin_edges[1:]
        ys_here[1:-1:2] = hist
        ys_here[2:-1:2] = hist

        xs_histo_series.append(xs_here)
        ys_histo_series.append(ys_here)

    plot(xs=xs_histo_series, ys=ys_histo_series, **kwargs)