This page was generated from docs/examples/DataSet/Offline plotting with categorical data.ipynb. Interactive online version: .
Offline plotting with categorical data¶
This notebook is a collection of plotting examples using the plot_dataset
function and caterogical (string-valued) data. The notebook should cover all possible permutations of categorical versus numerical data.
[1]:
%matplotlib inline
from pathlib import Path
import numpy as np
from qcodes.dataset import (
Measurement,
initialise_or_create_database_at,
load_or_create_experiment,
plot_dataset,
)
from qcodes.parameters import Parameter
Logging hadn't been started.
Activating auto-logging. Current session state plus future input saved.
Filename : /home/runner/.qcodes/logs/command_history.log
Mode : append
Output logging : True
Raw input log : False
Timestamping : True
State : active
Qcodes Logfile : /home/runner/.qcodes/logs/241230-15723-qcodes.log
[2]:
initialise_or_create_database_at(Path.cwd() / "offline_plotting_example_categorical.db")
exp = load_or_create_experiment("offline_plotting_experiment", "nosample")
1D plotting¶
Category is the independent parameter¶
With the category as the independent parameter, plot_dataset
will default to a bar plot as long as there is at most one value per category. If more than one value is found for any category a bar plot is not possible, and the plot_dataset
falls back to a scatter plot.
[3]:
voltage = Parameter("voltage", label="Voltage", unit="V", set_cmd=None, get_cmd=None)
fridge_config = Parameter(
"config", label="Fridge configuration", set_cmd=None, get_cmd=None
)
meas = Measurement(exp=exp)
meas.register_parameter(fridge_config, paramtype="text")
meas.register_parameter(voltage, setpoints=(fridge_config,))
with meas.run() as datasaver:
configurations = ["open", "outer chamber closed", "pumping", "closed"]
for configuration in configurations:
datasaver.add_result(
(fridge_config, configuration), (voltage, np.random.rand())
)
dataset = datasaver.dataset
Starting experimental run with id: 1.
[4]:
_ = plot_dataset(dataset)
[5]:
with meas.run() as datasaver:
configurations = ["open", "outer chamber closed", "pumping", "closed"]
for configuration in configurations:
datasaver.add_result(
(fridge_config, configuration), (voltage, np.random.rand())
)
datasaver.add_result((fridge_config, "open"), (voltage, np.random.rand()))
dataset = datasaver.dataset
_ = plot_dataset(dataset)
Starting experimental run with id: 2.
Category is the dependent parameter¶
With the categories as the dependent variable, i.e., the outcome of a measurement, the plot_dataset
defaults to a scatter plot.
Here is an example with made-up parameters and random values.
UNRESOLVED: How do we ensure the y-axis order?
[6]:
voltage = Parameter("voltage", label="Voltage", unit="V", set_cmd=None, get_cmd=None)
response = Parameter("response", label="Sample response", set_cmd=None, get_cmd=None)
meas = Measurement(exp=exp)
meas.register_parameter(voltage)
meas.register_parameter(response, paramtype="text", setpoints=(voltage,))
with meas.run() as datasaver:
for volt in np.linspace(0, 1, 50):
coinvalue = volt + 0.5 * np.random.randn()
if coinvalue < 0:
resp = "Bad"
elif coinvalue < 0.8:
resp = "Good"
else:
resp = "Excellent"
datasaver.add_result((voltage, volt), (response, resp))
dataset = datasaver.dataset
Starting experimental run with id: 3.
[7]:
_ = plot_dataset(dataset)
Both variables are categorical¶
For both variables being categorical, the plot_dataset
defaults to a scatter plot.
This case would typically be some summary of a large number of measurements.
[8]:
sample = Parameter("sample", label="Sample", unit="", set_cmd=None, get_cmd=None)
feature = Parameter("feature", label="Physical feature", set_cmd=None, get_cmd=None)
meas = Measurement(exp=exp)
meas.register_parameter(sample, paramtype="text")
meas.register_parameter(feature, paramtype="text", setpoints=(sample,))
with meas.run() as datasaver:
features = ["superconducting", "qubit", "clean states", "high bandwidth"]
for samp in ["Nanowire", "Silicon Chip", "SQUID", "Membrane"]:
feats = np.random.randint(1, 5)
for _ in range(feats):
datasaver.add_result(
(sample, samp), (feature, features[np.random.randint(0, 4)])
)
dataset = datasaver.dataset
Starting experimental run with id: 4.
[9]:
_ = plot_dataset(dataset)
2D plotting¶
Naming convention: the x-axis is horizontal, the y-axis is vertical, and the z-axis is out-of-plane.
Categorical data on the x-axis¶
Here is an example where different samples are tested for conductivity. The longer the name of the sample, the higher the conductivity.
[10]:
sample = Parameter("sample", label="Sample", unit="", set_cmd=None, get_cmd=None)
gate_voltage = Parameter(
"gate_v", label="Gate voltage", unit="V", set_cmd=None, get_cmd=None
)
conductance = Parameter(
"conductance", label="Conductance", unit="e^2/hbar", set_cmd=None, get_cmd=None
)
meas = Measurement(exp=exp)
meas.register_parameter(sample, paramtype="text")
meas.register_parameter(gate_voltage)
meas.register_parameter(conductance, setpoints=(sample, gate_voltage))
with meas.run() as datasaver:
for samp in ["Nanowire", "Silicon Chip", "SQUID", "Membrane"]:
gate_vs = np.linspace(0, 0.075, 75)
for gate_v in gate_vs:
datasaver.add_result(
(sample, samp),
(gate_voltage, gate_v),
(conductance, len(samp) * gate_v),
)
dataset = datasaver.dataset
Starting experimental run with id: 5.
[11]:
ax, _ = plot_dataset(dataset)
Categorical data on the y-axis¶
This situation is very similar to having categorical data on the x-axis. We reuse the same example.
[12]:
sample = Parameter("sample", label="Sample", unit="", set_cmd=None, get_cmd=None)
gate_voltage = Parameter(
"gate_v", label="Gate voltage", unit="V", set_cmd=None, get_cmd=None
)
conductance = Parameter(
"conductance", label="Conductance", unit="e^2/hbar", set_cmd=None, get_cmd=None
)
meas = Measurement(exp=exp)
meas.register_parameter(sample, paramtype="text")
meas.register_parameter(gate_voltage)
meas.register_parameter(conductance, setpoints=(gate_voltage, sample))
with meas.run() as datasaver:
for samp in ["Nanowire", "Silicon Chip", "SQUID", "Membrane"]:
gate_vs = np.linspace(0, 0.01, 75)
for gate_v in gate_vs:
datasaver.add_result(
(sample, samp),
(gate_voltage, gate_v),
(conductance, len(samp) * gate_v),
)
dataset = datasaver.dataset
Starting experimental run with id: 6.
[13]:
ax, _ = plot_dataset(dataset)
Categorical data on the z-axis¶
Categorical data on the z-axis behaves similarly to numerical data on the z-axis; what kind of plot we get depends on the structure of the setpoints (i.e. the x-axis and y-axis data). If the setpoints are on a grid, we get a heatmap. If not, we get a scatter plot.
Gridded setpoints¶
[14]:
bias_voltage = Parameter(
"bias_v", label="Bias voltage", unit="V", set_cmd=None, get_cmd=None
)
gate_voltage = Parameter(
"gate_v", label="Gate voltage", unit="V", set_cmd=None, get_cmd=None
)
useful = Parameter(
"usefulness", label="Usefulness of region", set_cmd=None, get_cmd=None
)
meas = Measurement(exp=exp)
meas.register_parameter(gate_voltage)
meas.register_parameter(bias_voltage)
meas.register_parameter(
useful, setpoints=(bias_voltage, gate_voltage), paramtype="text"
)
# a function to simulate the usefulness of a region
def get_usefulness(x, y):
val = np.sin(x) * np.sin(y)
if val < -0.4:
return "Useless"
if val < 0:
return "Bad"
if val < 0.5:
return "Possible"
return "Good"
with meas.run() as datasaver:
for bias_v in np.linspace(0, 3, 100):
for gate_v in np.linspace(-1, 1, 75):
datasaver.add_result(
(bias_voltage, bias_v),
(gate_voltage, gate_v),
(useful, get_usefulness(bias_v, gate_v)),
)
dataset = datasaver.dataset
Starting experimental run with id: 7.
[15]:
ax, cax = plot_dataset(dataset)
Scattered setpoints¶
The same example as above, but this time with setpoints not on a grid.
[16]:
bias_voltage = Parameter(
"bias_v", label="Bias voltage", unit="V", set_cmd=None, get_cmd=None
)
gate_voltage = Parameter(
"gate_v", label="Gate voltage", unit="V", set_cmd=None, get_cmd=None
)
useful = Parameter(
"usefulness", label="Usefulness of region", set_cmd=None, get_cmd=None
)
meas = Measurement(exp=exp)
meas.register_parameter(gate_voltage)
meas.register_parameter(bias_voltage)
meas.register_parameter(
useful, setpoints=(bias_voltage, gate_voltage), paramtype="text"
)
# a function to simulate the usefulness of a region
def get_usefulness(x, y):
val = np.sin(x) * np.sin(y)
if val < -0.4:
return "Useless"
if val < 0:
return "Bad"
if val < 0.5:
return "Possible"
return "Good"
with meas.run() as datasaver:
for bias_v in 3 * (np.random.rand(100)):
for gate_v in 2 * (np.random.rand(75) - 0.5):
datasaver.add_result(
(bias_voltage, bias_v),
(gate_voltage, gate_v),
(useful, get_usefulness(bias_v, gate_v)),
)
dataset = datasaver.dataset
Starting experimental run with id: 8.
[17]:
ax, cax = plot_dataset(dataset)
Categorical data on x-axis and z-axis¶
For completeness, we include two examples of this situation. One resulting in a grid and one resulting in a scatter plot. We reuse the example with the x- and y-axes having numerical data with just a slight modification.
[18]:
sample = Parameter("sample", label="Sample", set_cmd=None, get_cmd=None)
gate_voltage = Parameter(
"gate_v", label="Gate voltage", unit="V", set_cmd=None, get_cmd=None
)
useful = Parameter(
"usefulness", label="Usefulness of region", set_cmd=None, get_cmd=None
)
meas = Measurement(exp=exp)
meas.register_parameter(sample, paramtype="text")
meas.register_parameter(gate_voltage)
meas.register_parameter(useful, setpoints=(sample, gate_voltage), paramtype="text")
samples = ["nanowire", "2DEG", "spin qubit", "nanowire_alt"]
# a function to simulate the usefulness of a region
def get_usefulness(x, y):
x_num = samples.index(x) * 4 / len(samples)
val = np.sin(x_num) * np.sin(y)
if val < -0.4:
return "Useless"
if val < 0:
return "Bad"
if val < 0.5:
return "Possible"
return "Good"
with meas.run() as datasaver:
for samp in samples:
for gate_v in np.linspace(-1, 1, 75):
datasaver.add_result(
(sample, samp),
(gate_voltage, gate_v),
(useful, get_usefulness(samp, gate_v)),
)
dataset = datasaver.dataset
Starting experimental run with id: 9.
[19]:
ax, cax = plot_dataset(dataset)
[20]:
sample = Parameter("sample", label="Sample", set_cmd=None, get_cmd=None)
gate_voltage = Parameter(
"gate_v", label="Gate voltage", unit="V", set_cmd=None, get_cmd=None
)
useful = Parameter(
"usefulness", label="Usefulness of region", set_cmd=None, get_cmd=None
)
meas = Measurement(exp=exp)
meas.register_parameter(sample, paramtype="text")
meas.register_parameter(gate_voltage)
meas.register_parameter(useful, setpoints=(sample, gate_voltage), paramtype="text")
samples = ["nanowire", "2DEG", "spin qubit", "nanowire_alt"]
# a function to simulate the usefulness of a region
def get_usefulness(x, y):
x_num = samples.index(x) * 4 / len(samples)
val = np.sin(x_num) * np.sin(y)
if val < -0.4:
return "Useless"
if val < 0:
return "Bad"
if val < 0.5:
return "Possible"
return "Good"
with meas.run() as datasaver:
for samp in samples:
for gate_v in 2 * (np.random.rand(75) - 0.5):
datasaver.add_result(
(sample, samp),
(gate_voltage, gate_v),
(useful, get_usefulness(samp, gate_v)),
)
dataset = datasaver.dataset
Starting experimental run with id: 10.
[21]:
ax, cax = plot_dataset(dataset)
[ ]: