<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_trajectory2d_with_matplotlib( obs, plane='xy', max_count=10, figsize=6, legend=True, wireframe=False, grid=True, noaxis=False, plot_range=None, **kwargs):
 """ Make a 2D plot from received instance of TrajectoryObserver and show it on IPython notebook. Parameters obs : TrajectoryObserver TrajectoryObserver to render. plane : str, default 'xy' 'xy', 'yz', 'zx'. max_count : Integer, default 10 The maximum number of particles to show. If None, show all. figsize : float, default 6 Size of the plotting area. Given in inch. legend : bool, default True plot_range : tuple, default None Range for plotting. A triplet of pairs suggesting (rangex, rangey, rangez). If None, the minimum volume containing all the trajectories is used. """

    import matplotlib.pyplot as plt

    plane = plane.lower()
    if len(plane) != 2 or plane[0] not in ('x', 'y', 'z') or plane[1] not in ('x', 'y', 'z'):
        raise ValueError("invalid 'plane' argument [{}] was given.".format(repr(plane)))
    xidx = 0 if plane[0] == 'x' else (1 if plane[0] == 'y' else 2)
    yidx = 0 if plane[1] == 'x' else (1 if plane[1] == 'y' else 2)

    data = obs.data()
    if max_count is not None and len(data) > max_count:
        data = random.sample(data, max_count)

    wrange = __get_range_of_trajectories(data, plot_range)
    wrange = (wrange['x'], wrange['y'], wrange['z'])
    wrange = {'x': wrange[xidx], 'y': wrange[yidx]}
    fig, ax = __prepare_plot_with_matplotlib(
        wrange, figsize, grid, wireframe, noaxis)
    ax.set_xlabel(plane[0].upper())
    ax.set_ylabel(plane[1].upper())

    lines = []
    for i, y in enumerate(data):
        xarr, yarr, zarr = [], [], []
        for pos in y:
            xarr.append(pos[xidx])
            yarr.append(pos[yidx])

        lines.append((xarr, yarr))

    __plot_trajectory2d_with_matplotlib(lines, ax, **kwargs)

    # if legend:
    #     ax.legend(loc='best', shadow=True)
    if legend is not None and legend is not False:
        legend_opts = {"loc": "best", "shadow": True}
        if isinstance(legend, dict):
            legend_opts.update(legend)
        ax.legend(**legend_opts)
    plt.show()