Reusing code written with matplotlib in Dash

Hello,

I have a 4D visualization (with color as the 4th dimension) that was built using matplotlib3d. I have been asked to move this visualization to a web app and I would like to use Dash.

I am wondering if anyone has examples of code that integrates matplotlib in with their dash build or is the situation that you have to build your visualizations from the ground up with the dash syntax?

Here is an example of my code that I would like to “translate” into Dash syntax:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import animation
%matplotlib inline

#read in data.  Break it up for generate of approach and retract visulaizations.
data = pd.read_csv('PHASEdata.csv',header=None, skiprows=1)
z = data[0]
z_approach = z[:500]
z_retract = z[500:]


#Reshape data into len(z) arrays of 48x48 pixels and index.
pslist = []
for k in range(len(z)):
    phaseshift = data.iloc[k,1:] 
    ps = np.array(phaseshift)
    ps_reshape = np.reshape(ps,(48,48))
    pslist.append(ps_reshape)

#Create meshgrid unto which phase shift values can be mapped.
a = np.linspace(0, 47, 48)
b = np.linspace(0, 47, 48)
c = z_approach
x, z, y = np.meshgrid(a, c, b)

#Create list of phase intensities.
psasas = []
for k in range(len(c)):
    C = pslist[k]
    for i in range(len(a)):
        B = pslist[k][i]
        for j in range(len(b)):
            A = pslist[k][i][j]
            psasas.append(A)
l = psasas

#Generate plot
fig = plt.figure(figsize=(9,9))
ax = fig.add_subplot(111, projection='3d')
ax.scatter(x, y, z, c=l, alpha=0.4)
ax.set_xlabel('X(nm)', fontsize=15)
ax.set_ylabel('Y(nm)', fontsize=15)
ax.set_zlabel('Z(nm)', fontsize=15)
ax.set_title('3D Plot for the AFM Phase Shift of XXX', fontsize=20)
plt.show()

It seems that one of my issues is that the lists I generate are not one of the native data types that JSON, and by extension, Dash supports (aka objects, arrays, strings, numbers, booleans, and null). I am not sure how I can modify my code so it is html readable, but still am able to generate my plot. Is it even possible? If not, what would be my best bet going forward?

I am very new to programming, so any comments are helpful. Thank you in advance!

Yes, this is possible. You could use the html.Img component, fill out the src key with a base64 encoded version of the matplotlib plot. There is an example here: https://github.com/4QuantOSS/DashIntro/blob/master/notebooks/Tutorial.ipynb, which was shared in the Dash community forum here: Can I run dash app in jupyter.

1 Like

Did you try using the plotly.plot_mpl function on your figure directly? Or is that what gave the JSON serialization issues.

Given that you are doing a 3D scatter plot with few-ish points, it probably isn’t too tricky to just use the natively plotly tools because then you keep the 3D interactivity.

@chriddyp After playing around with the code, it seems to me that the hmtl.Img call inserts static figures into your Dash app, is that correct? Does it do so by running the code on your python backend, generating an image, and pulling the static image to your app?

Thank you for your quick response.

@KevinM I did not try applying the plotly.plot_mpl function. From the example it looks like you translate your figure from matplotlib syntax to plotly syntax and assign it to an object “plot_url”

n = 50
x, y, z, s, ew = np.random.rand(5, n)
c, ec = np.random.rand(2, n, 4)
area_scale, width_scale = 500, 5

fig, ax = plt.subplots()
sc = ax.scatter(x, y, c=c,
                s=np.square(s)*area_scale,
                edgecolor=ec,
                linewidth=ew*width_scale)
ax.grid()

plot_url = py.plot_mpl(fig)

Would I then call the “plot_url” object in my dash app? For example:

app.layout = html.Div([
    dcc.Graph(
        id='3D_plot',
        figure = {plot_url
        }
    )
])

I will continue playing around the code and see what I can do. Thank you for the leads.