All Downloads are FREE. Search and download functionalities are using the official Maven repository.

tech.tablesaw.plotly.traces.HistogramTrace Maven / Gradle / Ivy

package tech.tablesaw.plotly.traces;

import com.mitchellbosecke.pebble.error.PebbleException;
import com.mitchellbosecke.pebble.template.PebbleTemplate;
import java.io.IOException;
import java.io.StringWriter;
import java.io.UncheckedIOException;
import java.io.Writer;
import java.util.Map;
import tech.tablesaw.api.NumericColumn;
import tech.tablesaw.columns.Column;
import tech.tablesaw.plotly.Utils;
import tech.tablesaw.plotly.components.Marker;

public class HistogramTrace extends AbstractTrace {

  private final Object[] x;
  private final Object[] y;
  private final double opacity;
  private final int nBinsX;
  private final int nBinsY;
  private final boolean autoBinX;
  private final boolean autoBinY;
  private final Marker marker;
  private final HistNorm histNorm;
  private final HistFunc histFunc;

  public enum HistNorm {
    NONE(""),
    PERCENT("percent"),
    PROBABILITY("probability"),
    DENSITY("density"),
    PROBABILITY_DENSITY("probability density");

    private final String value;

    HistNorm(String value) {
      this.value = value;
    }

    @Override
    public String toString() {
      return value;
    }
  }

  public enum HistFunc {
    COUNT("count"),
    SUM("sum"),
    AVG("avg"),
    MIN("min"),
    MAX("max");

    private final String value;

    HistFunc(String value) {
      this.value = value;
    }

    @Override
    public String toString() {
      return value;
    }
  }

  public static HistogramBuilder builder(double[] values) {
    return new HistogramBuilder(values);
  }

  public static HistogramBuilder builder(NumericColumn values) {
    return new HistogramBuilder(values.asDoubleArray());
  }

  public static HistogramBuilder builder(
      Column xValues, NumericColumn values) {
    return new HistogramBuilder(xValues.asObjectArray(), values.asDoubleArray());
  }

  private HistogramTrace(HistogramBuilder builder) {
    super(builder);
    if (builder.horizontal) {
      this.x = builder.y;
      this.y = builder.x;
    } else {
      this.x = builder.x;
      this.y = builder.y;
    }
    this.histNorm = builder.histNorm;
    this.histFunc = builder.histFunc;
    this.nBinsX = builder.nBinsX;
    this.nBinsY = builder.nBinsY;
    this.autoBinX = builder.autoBinX;
    this.autoBinY = builder.autoBinY;
    this.opacity = builder.opacity;
    this.marker = builder.marker;
  }

  @Override
  public String asJavascript(int i) {
    Writer writer = new StringWriter();
    PebbleTemplate compiledTemplate;

    try {
      compiledTemplate = engine.getTemplate("trace_template.html");
      compiledTemplate.evaluate(writer, getContext(i));
    } catch (PebbleException e) {
      throw new IllegalStateException(e);
    } catch (IOException e) {
      throw new UncheckedIOException(e);
    }
    return writer.toString();
  }

  private Map getContext(int i) {

    Map context = super.getContext();
    context.put("variableName", "trace" + i);
    if (x != null) {
      context.put("x", Utils.dataAsString(x));
    }
    if (y != null) {
      context.put("y", Utils.dataAsString(y));
    }
    context.put("opacity", opacity);
    context.put("nBinsX", nBinsX);
    context.put("nBinsY", nBinsY);
    context.put("autoBinX", autoBinX);
    context.put("autoBinY", autoBinY);
    context.put("histnorm", histNorm);
    context.put("histfunc", histFunc);
    if (marker != null) {
      context.put("marker", marker);
    }

    return context;
  }

  public static class HistogramBuilder extends TraceBuilder {

    private final String type = "histogram";
    private int nBinsX;
    private int nBinsY;
    private boolean autoBinX;
    private boolean autoBinY;
    private boolean horizontal = false;
    private Object[] x;
    private Object[] y;
    private Marker marker;
    private HistNorm histNorm = HistNorm.NONE;
    private HistFunc histFunc = HistFunc.COUNT;

    private HistogramBuilder(double[] values) {
      this.x = doublesToObjects(values);
    }

    private HistogramBuilder(Object[] xValues, double[] yValues) {
      this.x = xValues;
      this.y = doublesToObjects(yValues);
    }

    /**
     * Specifies the maximum number of desired bins. This value will be used in an algorithm that
     * will decide the optimal bin size such that the histogram best visualizes the distribution of
     * the data.
     */
    public HistogramBuilder nBinsX(int bins) {
      this.nBinsX = bins;
      return this;
    }

    public HistogramBuilder nBinsY(int bins) {
      this.nBinsY = bins;
      return this;
    }

    /**
     * Determines whether or not the x axis bin attributes are picked by an algorithm. Note that
     * this should be set to False if you want to manually set the number of bins using the
     * attributes in xbins.
     *
     * 

Note also that this should be true (default) to use nbinsx to suggest a bin count */ public HistogramBuilder autoBinX(boolean autoBinX) { this.autoBinX = autoBinX; return this; } public HistogramBuilder autoBinY(boolean autoBinY) { this.autoBinY = autoBinY; return this; } public HistogramBuilder marker(Marker marker) { this.marker = marker; return this; } @Override public HistogramBuilder opacity(double opacity) { super.opacity(opacity); return this; } public HistogramBuilder horizontal(boolean horizontal) { this.horizontal = horizontal; return this; } @Override public HistogramBuilder showLegend(boolean b) { super.showLegend(b); return this; } /** * Specifies the type of normalization used for this histogram trace. If "", the span of each * bar corresponds to the number of occurrences (i.e. the number of data points lying inside the * bins). If "percent" / "probability", the span of each bar corresponds to the percentage / * fraction of occurrences with respect to the total number of sample points (here, the sum of * all bin HEIGHTS equals 100% / 1). If "density", the span of each bar corresponds to the * number of occurrences in a bin divided by the size of the bin interval (here, the sum of all * bin AREAS equals the total number of sample points). If "probability density", the area of * each bar corresponds to the probability that an event will fall into the corresponding bin * (here, the sum of all bin AREAS equals 1). * * @param histNorm The normalization type for the histogram * @return This HistogramBuilder */ public HistogramBuilder histNorm(HistNorm histNorm) { this.histNorm = histNorm; return this; } /** * Specifies the binning function used for this histogram trace. If "count", the histogram * values are computed by counting the number of values lying inside each bin. If "sum", "avg", * "min", "max", the histogram values are computed using the sum, the average, the minimum or * the maximum of the values lying inside each bin respectively. * * @param histFunc The function type * @return This HistogramBuilder */ public HistogramBuilder histFunc(HistFunc histFunc) { this.histFunc = histFunc; return this; } @Override public HistogramBuilder name(String name) { super.name(name); return this; } @Override public HistogramBuilder xAxis(String xAxis) { super.xAxis(xAxis); return this; } @Override public HistogramBuilder yAxis(String yAxis) { super.yAxis(yAxis); return this; } public HistogramBuilder y(double[] y) { this.y = doublesToObjects(y); return this; } public HistogramBuilder y(NumericColumn values) { this.y = values.asObjectArray(); return this; } public HistogramTrace build() { return new HistogramTrace(this); } @Override protected String getType() { return type; } } private static Object[] doublesToObjects(double[] doubles) { Object[] objects = new Object[doubles.length]; for (int i = 0; i < doubles.length; i++) { objects[i] = doubles[i]; } return objects; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy