<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def plot_wave(fps=30, frequency=1, wavetime=3, interactive=False, off_screen=False, notebook=None):
 """ Plot a 3D moving wave in a render window. Parameters fps : int, optional Maximum frames per second to display. Defaults to 30. frequency: float, optional Wave cycles per second. Defaults to 1 wavetime : float, optional The desired total display time in seconds. Defaults to 3 seconds. interactive: bool, optional Allows the user to set the camera position before the start of the wave movement. Default False. off_screen : bool, optional Enables off screen rendering when True. Used for automated testing. Disabled by default. Returns ------- points : np.ndarray Position of points at last frame. """

    # camera position
    cpos = [(6.879481857604187, -32.143727535933195, 23.05622921691103),
            (-0.2336056403734026, -0.6960083534590372, -0.7226721553894022),
            (-0.008900669873416645, 0.6018246347860926, 0.7985786667826725)]

    # Make data
    X = np.arange(-10, 10, 0.25)
    Y = np.arange(-10, 10, 0.25)
    X, Y = np.meshgrid(X, Y)
    R = np.sqrt(X**2 + Y**2)
    Z = np.sin(R)

    # Create and plot structured grid
    sgrid = vtki.StructuredGrid(X, Y, Z)

    # Get pointer to points
    points = sgrid.points.copy()

    # Start a plotter object and set the scalars to the Z height
    plotter = vtki.Plotter(off_screen=off_screen, notebook=notebook)
    plotter.add_mesh(sgrid, scalars=Z.ravel())
    plotter.camera_position = cpos
    plotter.plot(title='Wave Example', window_size=[800, 600],
                 # auto_close=False, interactive=interactive)
                 auto_close=False, interactive_update=True)

    # Update Z and display a frame for each updated position
    tdelay = 1. / fps
    tlast = time.time()
    tstart = time.time()
    while time.time() - tstart < wavetime:
        # get phase from start
        telap = time.time() - tstart
        phase = telap * 2 * np.pi * frequency
        Z = np.sin(R + phase)
        points[:, -1] = Z.ravel()

        # update plotting object, but don't automatically render
        plotter.update_coordinates(points, render=False)
        plotter.update_scalars(Z.ravel(), render=False)

        # Render and get time to render
        rstart = time.time()
        plotter.update()
        # plotter.render()
        rstop = time.time()

        # time delay
        tpast = time.time() - tlast
        if tpast < tdelay and tpast >= 0:
            time.sleep(tdelay - tpast)

        # get render time and actual FPS
        # rtime = rstop - rstart
        # act_fps = 1 / (time.time() - tlast + 1E-10)
        tlast = time.time()

    # Close movie and delete object
    plotter.close()

    return points