0

Imagine a rectangular plate with 8 surface-mounted sensors streaming continuous deformation values in z-direction during bending. I'm trying to get higher refresh rates in my 3D surface/wireframe plots using Matplotlib. ~30 fps would be more than sufficient for my needs.

I have so far used matplotlib's 3D wireframe plot along with Scipy's RBF interpolation function to visualize the deformation and obtain a smooth curve across the plate. The refresh rate of matplotlib is inherently poor, as mentioned in several answers already.

How would I implement blitting for this 3D plot? In this scenario, is blitting at all sufficient for higher refresh rates or is PyQtGraph necessary?

The code:

import numpy as np
import scipy as sp
import matplotlib.pyplot as plt
import scipy.interpolate
#from mpl_toolkits.mplot3d import Axes3D

# The first Four x and y values are the corners of the plate
# The next Eight x and y values correspond to the location of the sensors on the plate
x_coords = np.array([0, 500, 0, 500, 70, 70, 160, 250, 250, 340, 430, 430]);
y_coords = np.array([0, 0, 500, 500, 70, 340, 250, 160, 340, 250, 70, 430]);

# Just an example array of deformation values on the plate in the Z-direction. 
# The first Four z values are Zero because the corners of the plate are fixed during testing
z_deformation = np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                          [0, 0, 0, 0,-5, -5, -8, -15, -15, -8, -5, -5], 
                          [0, 0, 0, 0,-5, -5, -9, -16, -16, -9, -5, -5],
                          [0, 0, 0, 0,-6, -6, -10, -18, -18, -10, -6, -6],
                          [0, 0, 0, 0,-7, -7, -12, -20, -20, -12, -7, -7],
                          [0, 0, 0, 0,-8, -8, -15, -22, -22, -15, -8, -8]]);

# the Plate is 500x500 mm. Create a meshgrid of this size with 100 data points in x and y directions
B1,B2 = np.meshgrid(np.linspace(0, 500, 100), np.linspace(0, 500, 100), indexing='xy')

# Initialize plotting
plt.ion()
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d') 

for k in range(len(z_deformation)):

    # RBF Interpolation to smoothen the 8 sensor values 
    spline = sp.interpolate.Rbf(x_coords, y_coords, z_deformation[k,:], function='thin_plate', smooth=0, episilon=0)
    Z = spline(B1,B2)

    # Plotting the wireframe, labelling and setting axes limits
    ax.plot_wireframe(B1, B2, Z)
    ax.set_xlabel('X')
    ax.set_ylabel('Y')
    ax.set_zlabel('Deformation')
    ax.set_zlim(-50, 50) 

    plt.draw()
    plt.pause(0.5)

    # Clear axes at the end of every iteration
    ax.cla()
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • [Here](https://stackoverflow.com/questions/40126176/fast-live-plotting-in-matplotlib-pyplot/40139416#40139416) is how one could implement blitting. PyQtGraph will definitely be faster. – ImportanceOfBeingErnest Aug 12 '19 at 21:52
  • Thank you for the quick response. However, I have followed your answers on several posts and have come across the above link. But implementing blitting or PyQtGraph for 3D plots is being particularly challenging. Are there any examples out there for 3D? – Praneeth S Aug 12 '19 at 22:28
  • There should not be any difference between blitting for 2D or 3D plots. – ImportanceOfBeingErnest Aug 12 '19 at 22:30
  • **Regarding real-time plotting:** I was about to open a different question for this but would like your opinion already at this point. I have a python API which extracts the sensor values in real-time through a USB port. I intend to implement the code for static plotting inside this API and plot after each iteration. Given the above conditions, could you comment on whether blitting or PyQtGraph is better suited than the other? – Praneeth S Aug 12 '19 at 22:51
  • 1
    If your focus is on speed and you don't mind the bit of extra work, use PyQtGraph. If your focus is to get a nice visually appealing graph out for publication, use Matplotlib. – ImportanceOfBeingErnest Aug 12 '19 at 23:00

0 Answers0