示例#1
0
    def _create_plot(i, name, data, counter_two, display_plot=True):
        # Step the color on all subplots no just on plots
        # within the same axis/subplot
        # this is to match the qcodes-pyqtplot behaviour.
        title = "{} #{:03d}".format(CURRENT_EXPERIMENT["sample_name"],
                                    data.location_provider.counter)
        rasterized_note = " rasterized plot full data available in datafile"
        color = 'C' + str(counter_two)
        counter_two += 1
        plot = MatPlot()
        if issubclass(
                i.__class__,
                MultiChannelInstrumentParameter) or i._instrument is None:
            inst_meas_name = name
        else:
            inst_meas_name = "{}_{}".format(i._instrument.name, name)
        inst_meas_data = getattr(data, inst_meas_name)
        try:
            inst_meas_data = getattr(data, inst_meas_name)
        except AttributeError:
            inst_meas_name = "{}{}_0_0".format(i._instrument.name, name)
            inst_meas_data = getattr(data, inst_meas_name)
        inst_meta_data = __get_plot_type(inst_meas_data, plot)
        if 'z' in inst_meta_data:
            xlen, ylen = inst_meta_data['z'].shape
            rasterized = xlen * ylen > 5000
            po = plot.add(inst_meas_data, rasterized=rasterized)

            auto_color_scale_from_config(po.colorbar, auto_color_scale,
                                         inst_meta_data['z'],
                                         cutoff_percentile)
        else:
            rasterized = False
            plot.add(inst_meas_data, color=color)
            plot.subplots[0].grid()
        if rasterized:
            plot.subplots[0].set_title(title + rasterized_note)
        else:
            plot.subplots[0].set_title(title)
        title_list = plot.get_default_title().split(sep)
        title_list.insert(-1, CURRENT_EXPERIMENT['pdf_subfolder'])
        title = sep.join(title_list)
        plot.rescale_axis()
        plot.tight_layout()
        plot.save("{}_{:03d}.pdf".format(title, counter_two))
        if display_plot:
            plot.fig.canvas.draw()
            plt.show()
        else:
            plt.close(plot.fig)
示例#2
0
文件: plotting.py 项目: spauka/Qcodes
def plot_dataset(
    dataset: DataSetProtocol,
    axes: Optional[Union[matplotlib.axes.Axes,
                         Sequence[matplotlib.axes.Axes]]] = None,
    colorbars: Optional[Union[matplotlib.colorbar.Colorbar,
                              Sequence[matplotlib.colorbar.Colorbar]]] = None,
    rescale_axes: bool = True,
    auto_color_scale: Optional[bool] = None,
    cutoff_percentile: Optional[Union[Tuple[float, float], float]] = None,
    complex_plot_type: str = "real_and_imag",
    complex_plot_phase: str = "radians",
    **kwargs: Any,
) -> AxesTupleList:
    """
    Construct all plots for a given dataset

    Implemented so far:
       * 1D line and scatter plots
       * 2D plots on filled out rectangular grids
       * 2D scatterplots (fallback)

    The function can optionally be supplied with a matplotlib axes or a list
    of axes that will be used for plotting. The user should ensure that the
    number of axes matches the number of datasets to plot. To plot several (1D)
    dataset in the same axes supply it several times. Colorbar axes are
    created dynamically. If colorbar axes are supplied, they will be reused,
    yet new colorbar axes will be returned.

    The plot has a title that comprises run id, experiment name, and sample
    name.

    ``**kwargs`` are passed to matplotlib's relevant plotting functions
    By default the data in any vector plot will be rasterized
    for scatter plots and heatmaps if more than 5000 points are supplied.
    This can be overridden by supplying the `rasterized` kwarg.

    Args:
        dataset: The dataset to plot
        axes: Optional Matplotlib axes to plot on. If not provided, new axes
            will be created
        colorbars: Optional Matplotlib Colorbars to use for 2D plots. If not
            provided, new ones will be created
        rescale_axes: If True, tick labels and units for axes of parameters
            with standard SI units will be rescaled so that, for example,
            '0.00000005' tick label on 'V' axis are transformed to '50' on 'nV'
            axis ('n' is 'nano')
        auto_color_scale: If True, the colorscale of heatmap plots will be
            automatically adjusted to disregard outliers.
        cutoff_percentile: Percentile of data that may maximally be clipped
            on both sides of the distribution.
            If given a tuple (a,b) the percentile limits will be a and 100-b.
            See also the plotting tuorial notebook.
        complex_plot_type: Method for converting complex-valued parameters
            into two real-valued parameters, either ``"real_and_imag"`` or
            ``"mag_and_phase"``. Applicable only for the cases where the
            dataset contains complex numbers
        complex_plot_phase: Format of phase for plotting complex-valued data,
            either ``"radians"`` or ``"degrees"``. Applicable only for the
            cases where the dataset contains complex numbers

    Returns:
        A list of axes and a list of colorbars of the same length. The
        colorbar axes may be `None` if no colorbar is created (e.g. for
        1D plots)

    Config dependencies: (qcodesrc.json)
    """

    # handle arguments and defaults
    subplots_kwargs = {
        k: kwargs.pop(k)
        for k in set(kwargs).intersection(SUBPLOTS_KWARGS)
    }

    # sanitize the complex plotting kwargs
    if complex_plot_type not in ['real_and_imag', 'mag_and_phase']:
        raise ValueError(
            f'Invalid complex plot type given. Received {complex_plot_type} '
            'but can only accept "real_and_imag" or "mag_and_phase".')
    if complex_plot_phase not in ['radians', 'degrees']:
        raise ValueError(
            f'Invalid complex plot phase given. Received {complex_plot_phase} '
            'but can only accept "degrees" or "radians".')
    degrees = complex_plot_phase == "degrees"

    # Retrieve info about the run for the title

    experiment_name = dataset.exp_name
    sample_name = dataset.sample_name
    title = f"Run #{dataset.captured_run_id}, " \
            f"Experiment {experiment_name} ({sample_name})"

    alldata: NamedData = _get_data_from_ds(dataset)
    alldata = _complex_to_real_preparser(alldata,
                                         conversion=complex_plot_type,
                                         degrees=degrees)

    nplots = len(alldata)

    if isinstance(axes, matplotlib.axes.Axes):
        axeslist = [axes]
    else:
        axeslist = cast(List[matplotlib.axes.Axes], axes)
    if isinstance(colorbars, matplotlib.colorbar.Colorbar):
        colorbars = [colorbars]

    if axeslist is None:
        axeslist = []
        for i in range(nplots):
            fig, ax = plt.subplots(1, 1, **subplots_kwargs)
            axeslist.append(ax)
    else:
        if len(subplots_kwargs) != 0:
            raise RuntimeError(f"Error: You cannot provide arguments for the "
                               f"axes/figure creation if you supply your own "
                               f"axes. "
                               f"Provided arguments: {subplots_kwargs}")
        if len(axeslist) != nplots:
            raise RuntimeError(f"Trying to make {nplots} plots, but"
                               f"received {len(axeslist)} axes objects.")

    if colorbars is None:
        colorbars = len(axeslist) * [None]
    new_colorbars: List[matplotlib.colorbar.Colorbar] = []

    for data, ax, colorbar in zip(alldata, axeslist, colorbars):

        if len(data) == 2:  # 1D PLOTTING
            log.debug(f'Doing a 1D plot with kwargs: {kwargs}')

            xpoints = data[0]["data"]
            ypoints = data[1]["data"]

            plottype = get_1D_plottype(xpoints, ypoints)
            log.debug(f'Determined plottype: {plottype}')

            if plottype == '1D_line':
                # sort for plotting
                order = xpoints.argsort()
                xpoints = xpoints[order]
                ypoints = ypoints[order]

                with _appropriate_kwargs(plottype, colorbar is not None,
                                         **kwargs) as k:
                    ax.plot(xpoints, ypoints, **k)
            elif plottype == '1D_point':
                with _appropriate_kwargs(plottype, colorbar is not None,
                                         **kwargs) as k:
                    ax.scatter(xpoints, ypoints, **k)
            elif plottype == '1D_bar':
                with _appropriate_kwargs(plottype, colorbar is not None,
                                         **kwargs) as k:
                    ax.bar(xpoints, ypoints, **k)
            else:
                raise ValueError('Unknown plottype. Something is way wrong.')

            _set_data_axes_labels(ax, data)

            if rescale_axes:
                _rescale_ticks_and_units(ax, data, colorbar)

            new_colorbars.append(None)

            ax.set_title(title)

        elif len(data) == 3:  # 2D PLOTTING
            log.debug(f'Doing a 2D plot with kwargs: {kwargs}')

            if data[2]["shape"] is None:
                xpoints = data[0]["data"].flatten()
                ypoints = data[1]["data"].flatten()
                zpoints = data[2]["data"].flatten()
                plottype = get_2D_plottype(xpoints, ypoints, zpoints)
                log.debug(f"Determined plottype: {plottype}")
            else:
                xpoints = data[0]["data"]
                ypoints = data[1]["data"]
                zpoints = data[2]["data"]
                plottype = "2D_grid"

            how_to_plot = {
                '2D_grid': plot_on_a_plain_grid,
                '2D_equidistant': plot_on_a_plain_grid,
                '2D_point': plot_2d_scatterplot,
                '2D_unknown': plot_2d_scatterplot
            }
            plot_func = how_to_plot[plottype]

            with _appropriate_kwargs(plottype, colorbar is not None,
                                     **kwargs) as k:
                ax, colorbar = plot_func(xpoints, ypoints, zpoints, ax,
                                         colorbar, **k)

            _set_data_axes_labels(ax, data, colorbar)

            if rescale_axes:
                _rescale_ticks_and_units(ax, data, colorbar)

            auto_color_scale_from_config(colorbar, auto_color_scale, zpoints,
                                         cutoff_percentile)

            new_colorbars.append(colorbar)

            ax.set_title(title)

        else:
            log.warning('Multi-dimensional data encountered. '
                        f'parameter {data[-1]["name"]} depends on '
                        f'{len(data)-1} parameters, cannot plot '
                        f'that.')
            new_colorbars.append(None)

    if len(axeslist) != len(new_colorbars):
        raise RuntimeError("Non equal number of axes. Perhaps colorbar is "
                           "missing from one of the cases above")
    return axeslist, new_colorbars
示例#3
0
def plot_by_id(run_id: int,
               axes: Optional[Union[matplotlib.axes.Axes,
                              Sequence[matplotlib.axes.Axes]]]=None,
               colorbars: Optional[Union[matplotlib.colorbar.Colorbar,
                                   Sequence[
                                       matplotlib.colorbar.Colorbar]]]=None,
               rescale_axes: bool=True,
               auto_color_scale: Optional[bool]=None,
               cutoff_percentile: Optional[Union[Tuple[Number, Number], Number]]=None,
               **kwargs) -> AxesTupleList:
    """
    Construct all plots for a given run

    Implemented so far:
       * 1D line and scatter plots
       * 2D plots on filled out rectangular grids
       * 2D scatterplots (fallback)

    The function can optionally be supplied with a matplotlib axes or a list
    of axes that will be used for plotting. The user should ensure that the
    number of axes matches the number of datasets to plot. To plot several (1D)
    dataset in the same axes supply it several times. Colorbar axes are
    created dynamically. If colorbar axes are supplied, they will be reused,
    yet new colorbar axes will be returned.

    The plot has a title that comprises run id, experiment name, and sample
    name.

    ``**kwargs`` are passed to matplotlib's relevant plotting functions
    By default the data in any vector plot will be rasterized
    for scatter plots and heatmaps if more that 5000 points are supplied.
    This can be overridden by supplying the `rasterized` kwarg.

    Args:
        run_id:
            ID of the run to plot
        axes:
            Optional Matplotlib axes to plot on. If not provided, new axes
            will be created
        colorbars:
            Optional Matplotlib Colorbars to use for 2D plots. If not
            provided, new ones will be created
        rescale_axes: if True, tick labels and units for axes of parameters
            with standard SI units will be rescaled so that, for example,
            '0.00000005' tick label on 'V' axis are transformed to '50' on 'nV'
            axis ('n' is 'nano')
        auto_color_scale: if True, the colorscale of heatmap plots will be
            automatically adjusted to disregard outliers.
        cutoff_percentile: percentile of data that may maximally be clipped
            on both sides of the distribution.
            If given a tuple (a,b) the percentile limits will be a and 100-b.
            See also the plotting tuorial notebook.

    Returns:
        a list of axes and a list of colorbars of the same length. The
        colorbar axes may be None if no colorbar is created (e.g. for
        1D plots)

    Config dependencies: (qcodesrc.json)
    """

    # handle arguments and defaults
    subplots_kwargs = {k: kwargs.pop(k)
                       for k in set(kwargs).intersection(SUBPLOTS_KWARGS)}

    # Retrieve info about the run for the title
    dataset = load_by_id(run_id)
    experiment_name = dataset.exp_name
    sample_name = dataset.sample_name
    title = f"Run #{run_id}, Experiment {experiment_name} ({sample_name})"

    alldata = get_data_by_id(run_id)
    nplots = len(alldata)

    if isinstance(axes, matplotlib.axes.Axes):
        axes = [axes]
    if isinstance(colorbars, matplotlib.colorbar.Colorbar):
        colorbars = [colorbars]

    if axes is None:
        axes = []
        for i in range(nplots):
            fig, ax = plt.subplots(1, 1, **subplots_kwargs)
            axes.append(ax)
    else:
        if len(subplots_kwargs) != 0:
            raise RuntimeError(f"Error: You cannot provide arguments for the "
                               f"axes/figure creation if you supply your own "
                               f"axes. "
                               f"Provided arguments: {subplots_kwargs}")
        if len(axes) != nplots:
            raise RuntimeError(f"Trying to make {nplots} plots, but"
                               f"received {len(axes)} axes objects.")

    if colorbars is None:
        colorbars = len(axes)*[None]
    new_colorbars: List[matplotlib.colorbar.Colorbar] = []

    for data, ax, colorbar in zip(alldata, axes, colorbars):

        if len(data) == 2:  # 1D PLOTTING
            log.debug('Plotting by id, doing a 1D plot')

            xpoints = data[0]['data']
            ypoints = data[1]['data']

            plottype = get_1D_plottype(xpoints, ypoints)
            log.debug(f'Determined plottype: {plottype}')

            if plottype == 'line':
                # sort for plotting
                order = xpoints.argsort()
                xpoints = xpoints[order]
                ypoints = ypoints[order]

                ax.plot(xpoints, ypoints, **kwargs)
            elif plottype == 'point':
                ax.scatter(xpoints, ypoints, **kwargs)
            elif plottype == 'bar':
                ax.bar(xpoints, ypoints, **kwargs)
            else:
                raise ValueError('Unknown plottype. Something is way wrong.')

            _set_data_axes_labels(ax, data)

            if rescale_axes:
                _rescale_ticks_and_units(ax, data, colorbar)

            new_colorbars.append(None)

            ax.set_title(title)

        elif len(data) == 3:  # 2D PLOTTING
            log.debug('Plotting by id, doing a 2D plot')

            # From the setpoints, figure out which 2D plotter to use
            # TODO: The "decision tree" for what gets plotted how and how
            # we check for that is still unfinished/not optimised

            xpoints = flatten_1D_data_for_plot(data[0]['data'])
            ypoints = flatten_1D_data_for_plot(data[1]['data'])
            zpoints = flatten_1D_data_for_plot(data[2]['data'])

            plottype = get_2D_plottype(xpoints, ypoints, zpoints)

            log.debug(f'Determined plottype: {plottype}')

            how_to_plot = {'grid': plot_on_a_plain_grid,
                           'equidistant': plot_on_a_plain_grid,
                           'point': plot_2d_scatterplot,
                           'unknown': plot_2d_scatterplot}
            plot_func = how_to_plot[plottype]

            if colorbar is None and 'cmap' not in kwargs:
                kwargs['cmap'] = qc.config.plotting.default_color_map

            ax, colorbar = plot_func(xpoints, ypoints, zpoints, ax, colorbar,
                                     **kwargs)

            _set_data_axes_labels(ax, data, colorbar)

            if rescale_axes:
                _rescale_ticks_and_units(ax, data, colorbar)

            auto_color_scale_from_config(colorbar, auto_color_scale,
                                         zpoints, cutoff_percentile)

            new_colorbars.append(colorbar)

            ax.set_title(title)

        else:
            log.warning('Multi-dimensional data encountered. '
                        f'parameter {data[-1]["name"]} depends on '
                        f'{len(data)-1} parameters, cannot plot '
                        f'that.')
            new_colorbars.append(None)

    if len(axes) != len(new_colorbars):
        raise RuntimeError("Non equal number of axes. Perhaps colorbar is "
                           "missing from one of the cases above")
    return axes, new_colorbars
示例#4
0
    def _create_plot(plot, i, name, data, counter_two, j, k):
        """
        Args:
            plot: The plot object, either QtPlot() or MatPlot()
            i: The parameter to measure
            name: -
            data: The DataSet of the current measurement
            counter_two: The sub-measurement counter. Each measurement has a
                number and each sub-measurement has a counter.
            j: The current sub-measurement
            k: -
        """

        color = 'C' + str(counter_two)
        if issubclass(
                i.__class__,
                MultiChannelInstrumentParameter) or i._instrument is None:
            inst_meas_name = name
        else:
            parent_instr_name = (i._instrument.name +
                                 '_') if i._instrument else ''
            inst_meas_name = "{}{}".format(parent_instr_name, name)
        try:
            inst_meas_data = getattr(data, inst_meas_name)
        except AttributeError:
            inst_meas_name = "{}{}_0_0".format(parent_instr_name, name)
            inst_meas_data = getattr(data, inst_meas_name)

        inst_meta_data = __get_plot_type(inst_meas_data, plot)
        if useQT:
            plot.add(inst_meas_data, subplot=j + k + 1)
            plot.subplots[j + k].showGrid(True, True)
            if j == 0:
                plot.subplots[0].setTitle(title)
            else:
                plot.subplots[j + k].setTitle("")

            plot.fixUnitScaling(startranges)
            QtPlot.qc_helpers.foreground_qt_window(plot.win)

        else:
            if 'z' in inst_meta_data:
                xlen, ylen = inst_meta_data['z'].shape
                rasterized = xlen * ylen > 5000
                po = plot.add(inst_meas_data,
                              subplot=j + k + 1,
                              rasterized=rasterized)

                auto_color_scale_from_config(po.colorbar, auto_color_scale,
                                             inst_meta_data['z'],
                                             cutoff_percentile)
            else:
                rasterized = False
                plot.add(inst_meas_data, subplot=j + k + 1, color=color)
                plot.subplots[j + k].grid()
            if j == 0:
                if rasterized:
                    fulltitle = title + rasterized_note
                else:
                    fulltitle = title
                plot.subplots[0].set_title(fulltitle)
            else:
                if rasterized:
                    fulltitle = rasterized_note
                else:
                    fulltitle = ""
                plot.subplots[j + k].set_title(fulltitle)