def plot_freqs(self, ax=None, title='', **kw): if ax is None: ax = plt.gca() ax.set_title(title) amps_sorted = [ x for x, _ in sorted(zip(self.filt_amps, self.filt_freqs)) ] freqs_sorted = [ y for _, y in sorted(zip(self.filt_amps, self.filt_freqs)) ] ax.plot(amps_sorted, freqs_sorted, ".-") ax.scatter(self.excl_amps, self.excl_freqs, marker='x', color='C3') aa = np.linspace(min(self.amps), max(self.amps), 50) ax.plot(aa, np.polyval(self.poly_fit, aa), label='fit') set_xlabel(ax, "Amplitude", 'V') set_ylabel(ax, 'Detuning', 'Hz')
def plot_cal_points_hexbin(shots_0, shots_1, shots_2, xlabel: str, xunit: str, ylabel: str, yunit: str, title: str, ax, common_clims: bool = True, **kw): # Choose colormap alpha_cmaps = [] for cmap in [pl.cm.Blues, pl.cm.Reds, pl.cm.Greens]: my_cmap = cmap(np.arange(cmap.N)) my_cmap[:, -1] = np.linspace(0, 1, cmap.N) my_cmap = ListedColormap(my_cmap) alpha_cmaps.append(my_cmap) f = plt.gcf() hb2 = ax.hexbin(x=shots_2[0], y=shots_2[1], cmap=alpha_cmaps[2]) cb = f.colorbar(hb2, ax=ax) cb.set_label(r'Counts $|2\rangle$') hb1 = ax.hexbin(x=shots_1[0], y=shots_1[1], cmap=alpha_cmaps[1]) cb = f.colorbar(hb1, ax=ax) cb.set_label(r'Counts $|1\rangle$') hb0 = ax.hexbin(x=shots_0[0], y=shots_0[1], cmap=alpha_cmaps[0]) cb = f.colorbar(hb0, ax=ax) cb.set_label(r'Counts $|0\rangle$') if common_clims: clims = hb0.get_clim(), hb1.get_clim(), hb2.get_clim() clim = np.min(clims), np.max(clims) for hb in hb0, hb1, hb2: hb.set_clim(clim) set_xlabel(ax, xlabel, xunit) set_ylabel(ax, ylabel, yunit) ax.set_title(title)
def make_mux_ssro_histogram(data_dict, ch_name, title=None, ax=None, **kw): if ax is None: f, ax = plt.subplots() nr_of_qubits = data_dict['nr_of_qubits'] markers = itertools.cycle(('v', '<', '>', '^', 'd', 'o', 's', '*')) for i in range(2**nr_of_qubits): format_str = '{'+'0:0{}b'.format(nr_of_qubits) + '}' binning_string = format_str.format(i) ax.plot(data_dict['bin_centers {}'.format(ch_name)], data_dict['hist {} {}'.format(ch_name, binning_string)][0], linestyle='', marker=next(markers), alpha=.7, label=binning_string) legend_title = "Prep. state \n[%s]" % ', '.join(data_dict['qubit_names']) ax.legend(title=legend_title, loc=1) ax.set_ylabel('Counts') # arbitrary units as we use optimal weights set_xlabel(ax, ch_name, 'a.u.') if title is not None: ax.set_title(title)
def plot_chevron(x, y, Z, xlabel, xunit, ylabel, yunit, zlabel, zunit, title, ax, **kw): colormap = ax.pcolormesh( x, y, Z, cmap='viridis', # norm=norm, linewidth=0, rasterized=True, # assumes digitized readout vmin=0, vmax=1) set_xlabel(ax, xlabel, xunit) set_ylabel(ax, ylabel, yunit) ax.set_title(title) ax_divider = make_axes_locatable(ax) cax = ax_divider.append_axes('right', size='5%', pad='2%') cbar = plt.colorbar(colormap, cax=cax, orientation='vertical') cax.set_ylabel('L1 (%)') set_ylabel(cax, zlabel, zunit)
def plot_frequency(self, ax=None, title='Detuning frequency', nyquists=None, style=".-", show_demod_freq=True, **kw): if ax is None: ax = plt.gca() ax.set_title(title) if nyquists is None: nyquists = [self.nyquist_order] for n in nyquists: if show_demod_freq: ax.axhline(-self.demod_freq + self.sampling_rate * n, linestyle='--', c='grey') real_detuning = self.get_real_detuning(n) ax.plot(self.time, real_detuning, style) set_xlabel(ax, 'Time', 's') set_ylabel(ax, 'Frequency', 'Hz')
def plot_cz_trajectory(self, axs=None, show=True, which_gate="NE"): """ Plots the cz trajectory in frequency space. """ q_J2 = self.get("q_J2_%s" % which_gate) if axs is None: f, axs = plt.subplots(figsize=(5, 7), nrows=3, sharex=True) dac_amps = self._wave_dict["cz_%s" % which_gate] t = np.arange(0, len(dac_amps)) * 1 / self.sampling_rate() CZ_amp = dac_amps * self.get_dac_val_to_amp_scalefactor() CZ_eps = self.calc_amp_to_eps(CZ_amp, "11", "02", which_gate=which_gate) CZ_theta = wfl.eps_to_theta(CZ_eps, q_J2) axs[0].plot(t, np.rad2deg(CZ_theta), marker=".") axs[0].fill_between(t, np.rad2deg(CZ_theta), color="C0", alpha=0.5) set_ylabel(axs[0], r"$\theta$", "deg") axs[1].plot(t, CZ_eps, marker=".") axs[1].fill_between(t, CZ_eps, color="C0", alpha=0.5) set_ylabel(axs[1], r"$\epsilon_{11-02}$", "Hz") axs[2].plot(t, CZ_amp, marker=".") axs[2].fill_between(t, CZ_amp, color="C0", alpha=0.1) set_xlabel(axs[2], "Time", "s") set_ylabel(axs[2], r"Amp.", "V") # axs[2].set_ylim(-1, 1) axs[2].axhline(0, lw=0.2, color="grey") CZ_amp_pred = self.distort_waveform(CZ_amp)[:len(CZ_amp)] axs[2].plot(t, CZ_amp_pred, marker=".") axs[2].fill_between(t, CZ_amp_pred, color="C1", alpha=0.3) if show: plt.show() return axs
def make_phase_plot(t, phase, phase_err, title, ylim=None, ax=None, **kw): if ax is None: f, ax = plt.subplots() ax.errorbar(t, phase, phase_err, marker='.') ax.set_title(title) set_xlabel(ax, 'Gate separtion', 's') set_ylabel(ax, 'Phase', 'deg') mean_phase_tail = np.nanmean(phase[10:]) ax.axhline(mean_phase_tail, ls='-', c='grey', linewidth=.5) ax.axhline(mean_phase_tail + 10, ls=':', c='grey', label=r'$\pm$10 deg', linewidth=0.5) ax.axhline(mean_phase_tail - 10, ls=':', c='grey', linewidth=0.5) ax.axhline(mean_phase_tail + 5, ls='--', c='grey', label=r'$\pm$5 deg', linewidth=0.5) ax.axhline(mean_phase_tail - 5, ls='--', c='grey', linewidth=0.5) ax.legend() if ylim is None: try: ax.set_ylim(np.min([mean_phase_tail - 60, np.min(phase)]), np.max([mean_phase_tail + 40, np.max(phase)])) except ValueError: logging.warning("could not automatically determine axis limits.") # This happens if there is less than 10 measurements and the # "mean_phase_tail" is np.nan else: ax.set_ylim(ylim[0], ylim[1])
def plot_2D_ssro_histogram(xvals, yvals, zvals, xlabel, xunit, ylabel, yunit, zlabel, zunit, xlim=None, ylim=None, title='', cmap='viridis', cbarwidth='10%', cbarpad='5%', no_label=False, ax=None, cax=None, **kw): if ax is None: f, ax = plt.subplots() if not no_label: ax.set_title(title) # Plotting the "heatmap" out = flex_colormesh_plot_vs_xy(xvals, yvals, zvals, ax=ax, plot_cbar=True, cmap=cmap) # Adding the colorbar if cax is None: ax.ax_divider = make_axes_locatable(ax) ax.cax = ax.ax_divider.append_axes( 'right', size=cbarwidth, pad=cbarpad) else: ax.cax = cax ax.cbar = plt.colorbar(out['cmap'], cax=ax.cax) # Setting axis limits aspect ratios and labels ax.set_aspect(1) set_xlabel(ax, xlabel, xunit) set_ylabel(ax, ylabel, yunit) set_cbarlabel(ax.cbar, zlabel, zunit) if xlim is None: xlim = np.min([xvals, yvals]), np.max([xvals, yvals]) ax.set_xlim(xlim) if ylim is None: ylim = np.min([xvals, yvals]), np.max([xvals, yvals]) ax.set_ylim(ylim)
def plot_time_tuples(time_tuples, ax=None, time_unit='s', mw_duration=20e-9, fl_duration=240e-9, ro_duration=1e-6, ypos=None): if ax is None: f, ax = plt.subplots() mw_patch = mpatches.Patch(color='C0', label='Microwave') fl_patch = mpatches.Patch(color='C1', label='Flux') ro_patch = mpatches.Patch(color='C4', label='Measurement') if time_unit == 's': clock_cycle = 20e-9 elif time_unit == 'clocks': clock_cycle = 1 else: raise ValueError() for i, tt in enumerate(time_tuples): t_start, cw, targets, linenum = tt if 'meas' in cw: c = 'C4' width = ro_duration elif isinstance((list(targets)[0]), tuple): # Flux pulses c = 'C1' width = fl_duration else: # Microwave pulses c = 'C0' width = mw_duration if 'prepz' not in cw: for q in targets: if isinstance(q, tuple): for qi in q: ypos_i = qi if ypos is None else ypos ax.barh(ypos_i, width=width, left=t_start * clock_cycle, height=0.6, align='center', color=c, alpha=.8) else: # N.B. alpha is not 1 so that overlapping operations are easily # spotted. ypos_i = q if ypos is None else ypos ax.barh(ypos_i, width=width, left=t_start * clock_cycle, height=0.6, align='center', color=c, alpha=.8) ax.legend(handles=[mw_patch, fl_patch, ro_patch], loc=(1.05, 0.5)) set_xlabel(ax, 'Time', time_unit) set_ylabel(ax, 'Qubit', '#') ax.yaxis.set_major_locator(MaxNLocator(integer=True)) return ax
def run_full_analysis(self, normalize=False, plot_linecuts=True, linecut_log=False, colorplot_log=False, plot_all=True, save_fig=True, transpose=False, figsize=None, filtered=False, subtract_mean_x=False, subtract_mean_y=False, **kw): ''' Args: linecut_log (bool): log scale for the line cut? Remember to set the labels correctly. colorplot_log (string/bool): True/False for z axis scaling, or any string containing any combination of letters x, y, z for scaling of the according axis. Remember to set the labels correctly. ''' close_file = kw.pop('close_file', True) self.fig_array = [] self.ax_array = [] for i, meas_vals in enumerate(self.measured_values[:1]): if filtered: # print(self.measured_values) # print(self.value_names) if self.value_names[i] == 'Phase': self.measured_values[ i] = dm_tools.filter_resonator_visibility( x=self.sweep_points, y=self.sweep_points_2D, z=self.measured_values[i], **kw) if (not plot_all) & (i >= 1): break # Linecuts are above because somehow normalization applies to both # colorplot and linecuts otherwise. if plot_linecuts: fig, ax = plt.subplots(figsize=figsize) self.fig_array.append(fig) self.ax_array.append(ax) savename = 'linecut_{}'.format(self.value_names[i]) fig_title = '{} {} \nlinecut {}'.format( self.timestamp_string, self.measurementstring, self.value_names[i]) a_tools.linecut_plot( x=self.sweep_points, y=self.sweep_points_2D, z=self.measured_values[i], y_name=self.parameter_names[1], y_unit=self.parameter_units[1], log=linecut_log, # zlabel=self.zlabels[i], fig=fig, ax=ax, **kw) ax.set_title(fig_title) set_xlabel(ax, self.parameter_names[0], self.parameter_units[0]) # ylabel is value units as we are plotting linecuts set_ylabel(ax, self.value_names[i], self.value_units[i]) if save_fig: self.save_fig(fig, figname=savename, fig_tight=False, **kw) # Heatmap fig, ax = plt.subplots(figsize=figsize) self.fig_array.append(fig) self.ax_array.append(ax) if normalize: print("normalize on") self.ax_array.append(ax) savename = 'Heatmap_{}'.format(self.value_names[i]) fig_title = '{} {} \n{}'.format(self.timestamp_string, self.measurementstring, self.value_names[i]) if "xlabel" not in kw: kw["xlabel"] = self.parameter_names[0] if "ylabel" not in kw: kw["ylabel"] = self.parameter_names[1] if "zlabel" not in kw: kw["zlabel"] = self.value_names[0] if "x_unit" not in kw: kw["x_unit"] = self.parameter_units[0] if "y_unit" not in kw: kw["y_unit"] = self.parameter_units[1] if "z_unit" not in kw: kw["z_unit"] = self.value_units[0] # subtract mean from each row/column if demanded plot_zvals = meas_vals.transpose() if subtract_mean_x: plot_zvals = plot_zvals - np.mean(plot_zvals, axis=1)[:, None] if subtract_mean_y: plot_zvals = plot_zvals - np.mean(plot_zvals, axis=0)[None, :] a_tools.color_plot( x=self.sweep_points, y=self.sweep_points_2D, z=plot_zvals, # zlabel=self.sweept_val[i],u fig=fig, ax=ax, log=colorplot_log, transpose=transpose, normalize=normalize, **kw) ax.set_title(fig_title) set_xlabel(ax, kw["xlabel"], kw["x_unit"]) set_ylabel(ax, kw["ylabel"], kw["y_unit"]) if save_fig: self.save_fig(fig, figname=savename, fig_tight=False, **kw)
def plot_level_diagram(self, ax=None, show=True, which_gate="NE"): """ Plots the level diagram as specified by the q_ parameters. 1. Plotting levels 2. Annotating feature of interest 3. Adding legend etc. 4. Add a twin x-axis to denote scale in dac amplitude """ if ax is None: f, ax = plt.subplots() # 1. Plotting levels # maximum voltage of AWG in amp mode amps = np.linspace(-2.5, 2.5, 101) freqs = self.calc_amp_to_freq(amps, state="01", which_gate=which_gate) ax.plot(amps, freqs, label="$f_{01}$") ax.text( 0, self.calc_amp_to_freq(0, state="01", which_gate=which_gate), "01", color="C0", ha="left", va="bottom", clip_on=True, ) freqs = self.calc_amp_to_freq(amps, state="02", which_gate=which_gate) ax.plot(amps, freqs, label="$f_{02}$") ax.text( 0, self.calc_amp_to_freq(0, state="02", which_gate=which_gate), "02", color="C1", ha="left", va="bottom", clip_on=True, ) freqs = self.calc_amp_to_freq(amps, state="10", which_gate=which_gate) ax.plot(amps, freqs, label="$f_{10}$") ax.text( 0, self.calc_amp_to_freq(0, state="10", which_gate=which_gate), "10", color="C2", ha="left", va="bottom", clip_on=True, ) freqs = self.calc_amp_to_freq(amps, state="11", which_gate=which_gate) ax.plot(amps, freqs, label="$f_{11}$") ax.text( 0, self.calc_amp_to_freq(0, state="11", which_gate=which_gate), "11", color="C3", ha="left", va="bottom", clip_on=True, ) # 2. Annotating feature of interest ax.axvline(0, 0, 1e10, linestyle="dotted", c="grey") amp_J2 = self.calc_eps_to_amp(0, state_A="11", state_B="02", which_gate=which_gate) amp_J1 = self.calc_eps_to_amp(0, state_A="10", state_B="01", which_gate=which_gate) ax.axvline(amp_J2, ls="--", lw=1, c="C4") ax.axvline(amp_J1, ls="--", lw=1, c="C6") f_11_02 = self.calc_amp_to_freq(amp_J2, state="11", which_gate=which_gate) ax.plot([amp_J2], [f_11_02], color="C4", marker="o", label="11-02") ax.text( amp_J2, f_11_02, "({:.4f},{:.2f})".format(amp_J2, f_11_02 * 1e-9), color="C4", ha="left", va="bottom", clip_on=True, ) f_10_01 = self.calc_amp_to_freq(amp_J1, state="01", which_gate=which_gate) ax.plot([amp_J1], [f_10_01], color="C5", marker="o", label="10-01") ax.text( amp_J1, f_10_01, "({:.4f},{:.2f})".format(amp_J1, f_10_01 * 1e-9), color="C5", ha="left", va="bottom", clip_on=True, ) # 3. Adding legend etc. title = "Calibration visualization\n{}\nchannel {}".format( self.AWG(), self.cfg_awg_channel()) leg = ax.legend(title=title, loc=(1.05, 0.3)) leg._legend_box.align = "center" set_xlabel(ax, "AWG amplitude", "V") set_ylabel(ax, "Frequency", "Hz") ax.set_xlim(-2.5, 2.5) ax.set_ylim( 0, self.calc_amp_to_freq(0, state="02", which_gate=which_gate) * 1.1) # 4. Add a twin x-axis to denote scale in dac amplitude dac_val_axis = ax.twiny() dac_ax_lims = np.array( ax.get_xlim()) * self.get_amp_to_dac_val_scalefactor() dac_val_axis.set_xlim(dac_ax_lims) set_xlabel(dac_val_axis, "AWG amplitude", "dac") dac_val_axis.axvspan(1, 1000, facecolor=".5", alpha=0.5) dac_val_axis.axvspan(-1000, -1, facecolor=".5", alpha=0.5) # get figure is here in case an axis object was passed as input f = ax.get_figure() f.subplots_adjust(right=0.7) if show: plt.show() return ax
def render_wave(self, wave_id, show=True, time_units="lut_index", reload_pulses=True): """ Render a waveform. Args: wave_id: can be either the "name" of a waveform or the integer key in self._wave_dict. """ if wave_id not in self.LutMap().keys(): wave_id = get_wf_idx_from_name(wave_id, self.LutMap()) if reload_pulses: self.generate_standard_waveforms() fig, ax = plt.subplots(1, 1) if time_units == "lut_index": x = np.arange(len(self._wave_dict[wave_id][0])) ax.set_xlabel("Lookuptable index (i)") if self._voltage_min is not None: ax.vlines(2048, self._voltage_min, self._voltage_max, linestyle="--") elif time_units == "s": x = np.arange(len( self._wave_dict[wave_id][0])) / self.sampling_rate.get() if self._voltage_min is not None: ax.vlines( 2048 / self.sampling_rate.get(), self._voltage_min, self._voltage_max, linestyle="--", ) if len(self._wave_dict[wave_id]) == 2: ax.plot(x, self._wave_dict[wave_id][0], marker=".", label="chI") ax.plot(x, self._wave_dict[wave_id][1], marker=".", label="chQ") elif len(self._wave_dict[wave_id]) == 4: ax.plot(x, self._wave_dict[wave_id][0], marker=".", label="chGI") ax.plot(x, self._wave_dict[wave_id][1], marker=".", label="chGQ") ax.plot(x, self._wave_dict[wave_id][2], marker=".", label="chDI") ax.plot(x, self._wave_dict[wave_id][3], marker=".", label="chDQ") else: raise ValueError("waveform shape not understood") ax.legend() if self._voltage_min is not None: ax.set_facecolor("gray") ax.axhspan(self._voltage_min, self._voltage_max, facecolor="w", linewidth=0) ax.set_ylim(self._voltage_min * 1.1, self._voltage_max * 1.1) ax.set_xlim(0, x[-1]) if time_units == "s": set_xlabel(ax, "time", "s") set_ylabel(ax, "Amplitude", "V") if show: plt.show() return fig, ax