Analytics Vidhya
Published in

Analytics Vidhya

Dynamic Data Visualization in Angular with Plotly.js Events

Adding interactivity to data visualizations can contribute to better understanding of data. One of my favorite interactions is to use hover events to highlight data in another plots. Plotly.js provides events that make this kind of interaction possible, and their Angular library makes it easy to add to your next single page app.

Our goal:

Hover over graph 1 to highlight graph 2

Feel free to jump straight to the GitHub Repo if you’d prefer.

Getting Started

You can skip to the next section if you’re already comfortable with Plotly in Angular. First step, as usual, fire up an Angular project and grab some dependencies.

>> ng new
>> npm install --save angular-plotly.js plotly.js

We then configure and add the modules to the app.module.ts.

import { CommonModule } from '@angular/common';
import * as PlotlyJS from 'plotly.js/dist/plotly.js';
import { PlotlyModule } from 'angular-plotly.js';
// We have to supply the plotly.js module to the Angular
// library.
PlotlyModule.plotlyjs = PlotlyJS;

import { AppComponent } from './app.component';

@NgModule({
...
imports: [
BrowserModule,
CommonModule,
PlotlyModule,
...
],
...
})
export class AppModule { }

That’s sufficient configuration for us to use angular-plotly to do basic plotting. Plotly supports a large set of charts straight out of the box. There’s plenty of documentation for the various charts, but for demonstration purposes we’ll setup a simple bar chart and line chart.

...
export class AppComponent {
title = 'dynamic-plots';
// Bar Chart
graph1 = {
data: [
{ x: [1, 2, 3], y: [2, 3, 4], type: 'bar' },
],
layout: {title: 'Some Data to Hover Over'}
};
// Line chart
graph2 = {
data: [
{ x: [1, 2, 3, 4, 5], y: [1, 4, 9, 4, 1], type: 'scatter' },
{ x: [1, 2, 3, 4, 5], y: [1, 3, 6, 9, 6], type: 'scatter' },
{ x: [1, 2, 3, 4, 5], y: [1, 2, 4, 5, 6], type: 'scatter' },
],
layout: {title: 'Some Data to Highlight'}
};
}

We put some basic data into the app component as the properties graph1 and graph2. To render, we need to bind the data and layout to the plotly component like so.

<plotly-plot
[data]="graph1.data"
[layout]="graph1.layout"
[useResizeHandler]="true"></plotly-plot>

<plotly-plot
[data]="graph2.data"
[layout]="graph2.layout"
[useResizeHandler]="true"></plotly-plot>

If everything is wired up correctly, the app will render two plots when loaded.

Two plots, a bar chart on the left and a line chart on the right.
Basic Plots — We’ll animate these in the next section.

Animating with plotly events and RXJS

Our goal is to animate the line chart when a user hovers over the bar chart. As a simple animation, when the user hovers over the Nth bar, we’ll replot the line chart with only the Nth line. When the user isn’t hovering, we’ll show all of the lines.

Fundamentally, we need the line chart to subscribe to a stream of plot data. This is a great use for the RXJS BehaviorSubject. In RXJS, a subject is both an Observable and an EventEmitter. In our application, the plot must observe the stream of data, and we need to emit that stream in response to hover events. We use the BehaviorSubject because it allows us to set an initial value.

The app component:

...
export class AppComponent {
...// Initialize a behavior subject to return the line chart data
interactivePlotSubject$: Subject<any> = new BehaviorSubject<any>(this.graph2.data);
// We'll bind the hover event from plotly
hover(event: any): void {
// The hover event has a lot of information about cursor location.
// The bar the user is hovering over is in "pointIndex"
this.interactivePlotSubject$.next(
[this.graph2.data[event.points[0]].pointIndex]]
);
}
// Reset to default when hovering stops
mouseLeave(event): void {
this.interactivePlotSubject$.next(this.graph2.data);
}

The plotly Angular library exports the complete set of plotly events. We’re interested in two of them (hover) and (mouseleave). We modify the previous template to bind our methods:

    <plotly-plot
[data]="graph1.data"
[layout]="graph1.layout"
[useResizeHandler]="true"
(hover)="hover($event)"
(mouseleave)="mouseLeave($event)"></plotly-plot>

<plotly-plot
[data]="(interactivePlotSubject$ | async)"
[layout]="graph2.layout"
[useResizeHandler]="true"></plotly-plot>

That’s all it takes to get hover working:

Hover over graph 1 to highlight graph 2

Conclusion

I use hover events to bind multiple plots in a lot of my data visualization work. Plotly exposes a huge number of event types that enable rich data visualization experiences. Integrating them into dashboards is a huge UX win.

Angular and Plotly Logos
A Great Match

--

--

--

Analytics Vidhya is a community of Analytics and Data Science professionals. We are building the next-gen data science ecosystem https://www.analyticsvidhya.com

Recommended from Medium

Counter-Intuitive A/B Testing Tips That Help You Achieve Big Wins in 2020

An Ultimate Cheat Sheet for Numpy

Google Data Analytics Professional Certificate: My Review and Study Notes

What is __pycache__ in Python?

A Brief Introduction to Plotting in Python

Linked Data Goals for the Future

Blog post 1: Cassava Leaf distribution

AMA with Anthony Goldbloom, CEO of Kaggle, the open data science platform

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Andrew Matteson

Andrew Matteson

Mathematician, software engineer, computational biologist. I like playing with data.

More from Medium

Training an ML.NET Image Classification Model on GPUs using Google Colab

Python’s urllib. request for HTTP Requests

Node.js vs Python Programming

np arange with Example — pythonpip.com