Custom Scatterplot Matrix (SPLOM)

Hi, I know there is an ongoing issue in https://github.com/plotly/plotly_express/issues/42, but is there any way to modify individual subplots of plotly.graph_objects.splom? I’m trying to set diagonal to density charts. I tried building such a matrix from subplots, but I can’t make subplots to be linked on selection (selecting some points one one subplot doesn’t change selection on the other) like in graph_objects.splom.
My custom SPLOM looks like this:

fig = make_subplots(rows=4, cols=4)
features = ('a', 'b', 'c', 'd')
for i, colx in enumerate(features):
    for j, coly in enumerate(features):
        if i == j:  # diagonal as a density curve
            fig.add_trace(go.Scatter(x=x, y=y, fill='tozerox'), row=i+1, col=j+1)
        else:  # non-diagonal subplots
            fig.add_trace(go.Scatter(x=df[colx], y=df[coly], mode='markers'), row=i+1, col=j+1)
        fig.update_xaxes(title_text=colx, row=j+1, col=i+1)
        fig.update_yaxes(title_text=coly, row=j+1, col=i+1)

Is there any way to make selections interactive between subplots?
Thanks for any help!

Hi @eyebp,

No, you cannot insert a trace on the diagonal. help(go.splom.Diagonal) illustrates that the only update of the scatterplot matrix on its diagonal is to set diagonal_visible=False (True is the default value).

go.Splom class has a special definition (see the paragraph Scatter matrix (splom) with go.Splom in this tutorial https://plot.ly/python/splom/ . That’s why the user cannot access the subplot cells.

1 Like

Thanks for your reply,
Is it, however, possible to build something similar using subplots? I mean that data points will be linked between subplots when selected?

@eyebp figure_factory provides a method for creating scatterplot matrix, that unlike splom, can plot on diagonal a histogram or a boxplot. Unfortunately it isn’t maintained, and running the code below you’ll see deprecation warning.

But even with these warnings you can insert on diagonal the desired trace type.

First you should inspect fig.data (eventually fig.layout, too) to extract the data index corresponding to traces on the diagonal, and then remove these traces.

With fig.add_trace(trace, row=k, col=k) you can add a new trace on each diagonal cell.

import plotly.graph_objects as go
import plotly.figure_factory as ff

import numpy as np
import pandas as pd

df = pd.DataFrame(np.random.randn(20, 4),
                columns=['Column A', 'Column B', 'Column C', 'Column D'])

df['Fruit'] = pd.Series(['apple', 'apple', 'grape', 'apple', 'apple',
                                'grape', 'pear', 'pear', 'apple', 'pear',
                                'apple', 'apple', 'grape', 'apple', 'apple',
                                'grape', 'pear', 'pear', 'apple', 'pear'])


fig = ff.create_scatterplotmatrix(df, diag='histogram', index='Fruit',
                                  height=800, width=800)

2 Likes

Thanks but unfortunately they are not cross-linked, when I select some points there’s no action on other subplots :frowning:

You can add

fig.update_xaxes(matches='x')
fig.update_yaxes(matches='y')

but then it will also zoom on the histogram subplots which might look weird…

1 Like

@empet https://github.com/plotly/plotly.py/pull/1899 should fix the warnings, thanks for the notice :slight_smile:

2 Likes

Hi, thanks! however in my case there is a restriction addressing backend, so probably custom JS script is the only way…