is a JavaScript graphing library that enables interactivity in python and R charts.

Note: is currently in beta support in both Periscope’s Python and R environments. Please send any feedback or requests to the solutions team via live chat or

Note: Dash is not supported

Leveraging can be added to the python or R environment by importing it like any other supported library:

import plotly.plotly as py
from plotly import graph_objs as go

To pass Plot.y interactive plots to Periscope for visualization, pass the figure into periscope.plotly():


The Mode Bar is off by default. It can be enabled by including the following into the output.

For Python 2.7 & 3.6, pass the configurations into periscope.plotly():


For R, pass the configurations directly into the figure:

p <- plot_ly(data = iris, x = ~Sepal.Length, y = ~Petal.Length, type="scatter", mode="markers") %>% config(displayModeBar = TRUE)

Python Example: Sankey Chart

This is an example Python script which uses to make a Sankey chart (example shown above).

# SQL output is imported as a dataframe variable called 'df'
import pandas as pd
import numpy as np

   '#1f77b4',  # muted blue
   '#ff7f0e',  # safety orange
   '#2ca02c',  # cooked asparagus green
   '#d62728',  # brick red
   '#9467bd',  # muted purple
   '#e377c2',  # raspberry yogurt pink
   '#7f7f7f',  # middle gray
   '#bcbd22',  # curry yellow-green
   '#17becf'   # blue-teal

def color(i):

def rgb_from_hex(hex):
 h = hex.lstrip('#')
 return ",".join(str((int(h[i:i+2], 16))) for i in (0, 2 ,4))

def is_circular(df_agg, row):
  circular_reference = df_agg.query(f'prior_stage_index == {row["stage_index"]} & stage_index == {row["prior_stage_index"]}')
  if circular_reference.size == 0:
   return False
  elif circular_reference['count'].iloc[0] > row['count']:
   return True
   return False

df.columns = [c.lower() for c in df.columns]

stages = df.groupby(['stage_name']).size().reset_index()[['stage_name']]
stages['stage_index'] = stages.index
stages['color'] = stages.apply(lambda r: color(r['stage_index']), axis=1)

# print(stages)
df['stage_index'] = df.apply(lambda r: stages.loc[stages['stage_name'] == r['stage_name']]['stage_index'].iloc[0], axis=1)
df['prior_stage_index'] = df.groupby('unique_id').stage_index.shift()

df = df[np.isfinite(df['prior_stage_index'])]

df['prior_stage_name'] = df.apply(lambda r: stages.loc[stages['stage_index'] == r['prior_stage_index']]['stage_name'].iloc[0], axis=1)

df['prior_stage_index'] = df['prior_stage_index'].astype(int)

df_agg = df.groupby(['prior_stage_index', 'prior_stage_name', 'stage_index', 'stage_name']).size().reset_index(name='count')

df_agg['is_circular'] = df_agg.apply(lambda row: is_circular(df_agg, row), axis=1)
df_agg = df_agg.query('is_circular == False')

priors = df_agg['prior_stage_index']
ends = stages.query('stage_index not in @priors')

df_agg['color'] = df_agg.apply(lambda r: f'rgba({rgb_from_hex(color(r["prior_stage_index"]))},{.95 if r["stage_index"] in ends["stage_index"] else .25})', axis=1)

   pad = 20,
   thickness = 5,

layout =  dict(
   font = dict(
     size = 16
   hoverlabel = dict(
       bgcolor = 'purple'

fig = dict(data=[data], layout=layout)

Our support team is ready to help