Skip to main content
Version: 26.10.0

Creating histograms in Muze

Histogram is a graphical display of data using bars of different heights.It is similar to a Bar Chart but a histogram groups numbers into ranges .The height of each bar shows how many fall into each range which help us to decide what ranges to use.

Lets prepare our data​

The data is as:

[
  {
    "delay": 20,
    "distance": 570,
    "time": 6.833333333333333
  },
  {
    "delay": 7,
    "distance": 588,
    "time": 6.833333333333333
  },
  {
    "delay": 16,
    "distance": 590,
    "time": 6.883333333333333
  },
  {
    "delay": -19,
    "distance": 1797,
    "time": 6.916666666666667
  }
]

We will create a histogram illustrating the number of flights vs their delay.

Let's create a Datamodel instance from the raw data and some bins depicting the delay intervals.

const { muze } = viz;

const DelayField = "delay";
const DistanceField = "distance";
const TimeField = "time";

const data = [
  {
    delay: 20,
    distance: 570,
    time: 6.833333333333333,
  },
  {
    delay: 7,
    distance: 588,
    time: 6.833333333333333,
  },
  {
    delay: 16,
    distance: 590,
    time: 6.883333333333333,
  },
  {
    delay: -19,
    distance: 1797,
    time: 6.916666666666667,
  },
  {
    delay: -28,
    distance: 1864,
    time: 6.916666666666667,
  },
  {
    delay: -10,
    distance: 1481,
    time: 7,
  },
  {
    delay: -10,
    distance: 361,
    time: 7,
  },
  {
    delay: -28,
    distance: 1235,
    time: 7,
  },
  {
    delay: -3,
    distance: 256,
    time: 7,
  },
  {
    delay: -3,
    distance: 588,
    time: 7,
  },
  {
    delay: -4,
    distance: 423,
    time: 7,
  },
  {
    delay: -4,
    distance: 612,
    time: 7,
  },
  {
    delay: -5,
    distance: 1090,
    time: 7,
  },
  {
    delay: -5,
    distance: 296,
    time: 7,
  },
  {
    delay: 25,
    distance: 369,
    time: 2,
  },
  {
    delay: 22,
    distance: 110,
    time: 6,
  },
  {
    delay: 29,
    distance: 345,
    time: 7,
  },
  {
    delay: 33,
    distance: 407,
    time: 7,
  },
  {
    delay: -6,
    distance: 325,
    time: 7,
  },
  {
    delay: -7,
    distance: 236,
    time: 7,
  },
  {
    delay: 0,
    distance: 223,
    time: 7,
  },
  {
    delay: 0,
    distance: 303,
    time: 7,
  },
];

const schema = [
  {
    name: DelayField,
    type: "measure",
  },
  {
    name: DistanceField,
    type: "measure",
  },
  {
    name: TimeField,
    type: "measure",
  },
];

const formattedData = muze.DataModel.loadDataSync(data, schema);
let rootData = new muze.DataModel(formattedData);

// Bins
const bins = new Array(200)
  .fill()
  .map((d, i) => i - 60)
  .map((d, i) => [d * 10, (d + 1) * 10]);

Then lets create a new variable in our datamodel instance for the bins:

const DelayRangeField = 'delay_range';

const binnedDM = rootData.calculateVariable(
  {
      name: DelayRangeField,
      type: 'dimension'
  },
  [DelayField], 
  (no) => {
    const bin = bins.find(range => no >= range[0] && no <= range[1]);
    return bin ? bin.join(' - ') : undefined;
  };
);

Add a counter for each flight occurrence in each bin:

const FlightsField = "#Flights";

const dm = binnedDM.calculateVariable(
  {
    name: FlightsField,
    type: "measure",
  },
  [DelayField],
  () => 1,
);

Let's prepare our canvas:

const DelayLabelText = "Delay";

muze
  .canvas()
  .rows([FlightsField])
  .columns([DelayRangeField])
  .config({
    axes: {
      x: {
        padding: 0,
        name: DelayLabelText,
        tickFormat: (val) => val.rawValue.split(" - ")[0],
      },
      y: {
        show: false,
        numberOfTicks: 5,
      },
    },
    border: {
      // Hide the layout borders for better visibility
      showValueBorders: {
        left: false,
        bottom: false,
      },
    },
    sort: {
      [DelayRangeField]: (a, b) => {
        const [a1, a2] = a
          .split(" - ")
          .filter((d) => d)
          .map(Number);
        const [b1, b2] = b
          .split(" - ")
          .filter((d) => d)
          .map(Number);
        return a1 - b1;
      },
    },
  })
  .layers([
    {
      mark: "bar",
      transition: {
        disabled: true,
      },
      encoding: {
        strokeWidth: {
          value: "1px",
        },
      },
      interaction: {
        highlight: {
          style: {
            "stroke-width": "2px",
          },
        },
      },
      className: "histogram-bar",
    },
  ])
  .title("Airline arrival delay")
  .data(dm)
  .width(650)
  .height(500)
  .mount("#chart");