<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def scatter3d_and_projections(data_list, channels=[0,1,2], xscale='logicle', yscale='logicle', zscale='logicle', xlabel=None, ylabel=None, zlabel=None, xlim=None, ylim=None, zlim=None, color=None, figsize=None, savefig=None, **kwargs):
 """ Plot a 3D scatter plot and 2D projections from FCSData objects. `scatter3d_and_projections` creates a 3D scatter plot and three 2D projected scatter plots in four different axes for each FCSData object in `data_list`, in the same figure. Parameters data_list : FCSData object, or list of FCSData objects Flow cytometry data to plot. channels : list of int, list of str Three channels to use for the plot. savefig : str, optional The name of the file to save the figure to. If None, do not save. Other parameters xscale : str, optional Scale of the x axis, either ``linear``, ``log``, or ``logicle``. yscale : str, optional Scale of the y axis, either ``linear``, ``log``, or ``logicle``. zscale : str, optional Scale of the z axis, either ``linear``, ``log``, or ``logicle``. xlabel : str, optional Label to use on the x axis. If None, attempts to extract channel name from last data object. ylabel : str, optional Label to use on the y axis. If None, attempts to extract channel name from last data object. zlabel : str, optional Label to use on the z axis. If None, attempts to extract channel name from last data object. xlim : tuple, optional Limits for the x axis. If None, attempts to extract limits from the range of the last data object. ylim : tuple, optional Limits for the y axis. If None, attempts to extract limits from the range of the last data object. zlim : tuple, optional Limits for the z axis. If None, attempts to extract limits from the range of the last data object. color : matplotlib color or list of matplotlib colors, optional Color for the scatter plot. It can be a list with the same length as `data_list`. If `color` is not specified, elements from `data_list` are plotted with colors taken from the module-level variable `cmap_default`. figsize : tuple, optional Figure size. If None, use matplotlib's default. kwargs : dict, optional Additional parameters passed directly to matploblib's ``scatter``. Notes ----- `scatter3d_and_projections` uses matplotlib's ``scatter``, with the 3D scatter plot using a 3D projection. Additional keyword arguments provided to `scatter3d_and_projections` are passed directly to ``scatter``. """

    # Check appropriate number of channels
    if len(channels) != 3:
        raise ValueError('three channels need to be specified')

    # Create figure
    plt.figure(figsize=figsize)

    # Axis 1: channel 0 vs channel 2
    plt.subplot(221)
    scatter2d(data_list,
              channels=[channels[0], channels[2]],
              xscale=xscale,
              yscale=zscale,
              xlabel=xlabel,
              ylabel=zlabel,
              xlim=xlim,
              ylim=zlim,
              color=color,
              **kwargs)

    # Axis 2: 3d plot
    ax_3d = plt.gcf().add_subplot(222, projection='3d')
    scatter3d(data_list,
              channels=channels,
              xscale=xscale,
              yscale=yscale,
              zscale=zscale,
              xlabel=xlabel,
              ylabel=ylabel,
              zlabel=zlabel,
              xlim=xlim,
              ylim=ylim,
              zlim=zlim,
              color=color,
              **kwargs)

    # Axis 3: channel 0 vs channel 1
    plt.subplot(223)
    scatter2d(data_list,
              channels=[channels[0], channels[1]],
              xscale=xscale,
              yscale=yscale,
              xlabel=xlabel,
              ylabel=ylabel,
              xlim=xlim,
              ylim=ylim,
              color=color,
              **kwargs)

    # Axis 4: channel 2 vs channel 1
    plt.subplot(224)
    scatter2d(data_list,
              channels=[channels[2], channels[1]],
              xscale=zscale,
              yscale=yscale,
              xlabel=zlabel,
              ylabel=ylabel,
              xlim=zlim,
              ylim=ylim,
              color=color,
              **kwargs)

    # Save if necessary
    if savefig is not None:
        plt.tight_layout()
        plt.savefig(savefig, dpi=savefig_dpi)
        plt.close()