The matplotlib library is very capable but lacks interactiveness, especially inside Jupyter Notebook. I would like a good offline plotting tool like plot.ly.
4 Answers
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)
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.
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!
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)
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
)
ipywidgets
(examples at github.com/ipython/ipywidgets/blob/master/docs/source/examples/…) orbokeh
(bokeh.pydata.org/en/latest). $\endgroup$