13
$\begingroup$

The matplotlib library is very capable but lacks interactiveness, especially inside Jupyter Notebook. I would like a good offline plotting tool like plot.ly.

$\endgroup$
1

4 Answers 4

10
$\begingroup$

There is an awesome library called MPLD3 that generates interactive D3 plots.

This code produces an HTML interactive plot of the popular iris dataset that is compatible with Jupyter Notebook. When the paintbrush is selected, it allows you to select a subset of data to be highlighted among all of the plots. When the cross-arrow is selected, it allows you to to mouseover the data point and see information about the original data. This functionality is very useful when doing exploratory data analysis.

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sb
import mpld3
from mpld3 import plugins
%matplotlib inline

iris = sb.load_dataset('iris')
from sklearn.preprocessing import StandardScaler
X = pd.get_dummies(iris)
X_scal = StandardScaler().fit_transform(X)

dim = 3
from sklearn.decomposition import PCA
pca = PCA(n_components = dim)
Y_sklearn = pca.fit_transform(X_scal)

# Define some CSS to control our custom labels
css = """
table
{
  border-collapse: collapse;
}
th
{
  color: #ffffff;
  background-color: #000000;
}
td
{
  background-color: #cccccc;
}
table, th, td
{
  font-family:Arial, Helvetica, sans-serif;
  border: 1px solid black;
  text-align: right;
}
"""

fig, ax = plt.subplots(dim,dim, figsize=(6,6))
fig.subplots_adjust(hspace=.4, wspace=.4)
tooltip = [None]*dim

N = 200
index = np.random.choice(range(Y_sklearn.shape[0]),size=N)

for m in range(dim):
    for n in range(m+1):
        ax[m,n].grid(True, alpha=0.3)
        scatter = ax[m,n].scatter(Y_sklearn[index,m],Y_sklearn[index,n],alpha=.05)

        labels = []
        for i in index:
            label = X.ix[[i], :].T.astype(int)
            label.columns = ['Row {0}'.format(X.index[i])]
            labels.append(str(label.to_html()))

        ax[m,n].set_xlabel('Component ' + str(m) )
        ax[m,n].set_ylabel('Component ' + str(n) )
        #ax[m,n].set_title('HTML tooltips', size=20)

        tooltip[m] = plugins.PointHTMLTooltip(scatter, labels,
                                           voffset=20, hoffset=20, css=css)
        plugins.connect(fig, tooltip[m])

plugins.connect(fig, plugins.LinkedBrush(scatter))
test = mpld3.fig_to_html(fig=fig)

with open("Output.html", "w") as text_file:
    text_file.write(test)

See it in action on my blog.

Update [July 9, 2016]: I just found out that Plot.ly has an offline mode and is now open source. It has a lot of the bells and whistles prepackaged, but MPLD3 may still be appropriate in some cases.

$\endgroup$
3
$\begingroup$

I would prefer this to be a comment instead of an answer, as my intention is not to plug/advertise, but I am currently working on my thesis which may be of interest to you as it kind of does what you want. In reality it is a clustering visualization tool, but if you use k-means with k=1 you have an interactive plot where you can search for terms, select an area and see the content of each node, and other stuff. Take a look and see if it works for you!

$\endgroup$
1
  • $\begingroup$ Cool! I'll have a look. $\endgroup$ Jun 1, 2016 at 1:45
1
$\begingroup$

I highly recommend using PlotlyExpress instead

This code is plotting the first 3 components on the iris dataset

    import plotly.express as px
    from sklearn.datasets import load_iris

    from sklearn.decomposition import PCA
    from sklearn.preprocessing import StandardScaler, FunctionTransformer
    from sklearn.pipeline import Pipeline

    X, y = load_iris(return_X_y= True)

    pca = Pipeline([("standarize", StandardScaler()), ("pca",PCA(n_components = 3)), ("dataframe", FunctionTransformer(lambda x: pd.DataFrame(x, columns = ["first_comp", "second_comp", "third_comp"])))]).fit(X)
    X3D = pca.transform(X)
    px.scatter_3d(x = "first_comp", y = "second_comp",z = "third_comp", data_frame= X3D, color= y)

enter image description here

$\endgroup$
0
$\begingroup$

A very fine choice, plotly is...

In my case, i was trying to plot similar designation based on skills, where skills was a word2vec embedding of 300 dimensions; brought it to a 3 dimension vector space, and using plotly Scatter3D, i was able to plot a 3D scatterplot for the same.

Et Viola!! Got an awesome 3 dimension graph, with hover and enlarge functionality. And best part is it can be exported as an html file, making it a plug and play suitable for any other PC, just drag and drop in a browser (included in the code below).

Can anything BEE anymore simpler

from plotly.offline import plot
from plotly.graph_objs import *
import numpy as np

# x = np.random.randn(2000)
# y = np.random.randn(2000)

# Instead of simply calling plot(...), store your plot as a variable and pass it to displayHTML().
# Make sure to specify output_type='div' as a keyword argument.
# (Note that if you call displayHTML() multiple times in the same cell, only the last will take effect.)

p = plot(
  [
    Scatter3d(x=skills_df[0], y=skills_df[1], z=skills_df[2], text= skills_df['designation'], mode='markers', marker=Marker(color=skills_df['cluster_number'], size=3, opacity=0.5, colorscale='Viridis'))
  ],
  output_type='div'
#   filename='/dbfs/FileStore/tables/lnkdn_jobroles_viridis.html' turn it on to save the file
)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.