qcodespp 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. qcodespp/__init__.py +77 -0
  2. qcodespp/actions.py +237 -0
  3. qcodespp/data/__init__.py +0 -0
  4. qcodespp/data/data_array.py +555 -0
  5. qcodespp/data/data_set.py +926 -0
  6. qcodespp/data/format.py +338 -0
  7. qcodespp/data/gnuplot_format.py +425 -0
  8. qcodespp/data/hdf5_format.py +537 -0
  9. qcodespp/data/hdf5_format_hickle.py +63 -0
  10. qcodespp/data/io.py +241 -0
  11. qcodespp/data/location.py +171 -0
  12. qcodespp/instrument_drivers/Keysight/Keysight_34450A.py +9 -0
  13. qcodespp/instrument_drivers/Keysight/__init__.py +0 -0
  14. qcodespp/instrument_drivers/Keysight/private/Keysight_344xxA.py +456 -0
  15. qcodespp/instrument_drivers/Keysight/private/__init__.py +0 -0
  16. qcodespp/instrument_drivers/Lakeshore/Model_340.py +483 -0
  17. qcodespp/instrument_drivers/Lakeshore/__init__.py +0 -0
  18. qcodespp/instrument_drivers/QDevil/159fit_params_high_latest.json +386 -0
  19. qcodespp/instrument_drivers/QDevil/159fit_params_low_latest.json +386 -0
  20. qcodespp/instrument_drivers/QDevil/QDAC2.py +3229 -0
  21. qcodespp/instrument_drivers/QDevil/QDAC2_Array.py +300 -0
  22. qcodespp/instrument_drivers/QDevil/QSwitch_elab.py +652 -0
  23. qcodespp/instrument_drivers/QDevil/__init__.py +0 -0
  24. qcodespp/instrument_drivers/ZI/ZIHF2LI.py +415 -0
  25. qcodespp/instrument_drivers/ZI/ZIMFLI.py +764 -0
  26. qcodespp/instrument_drivers/ZI/ZIMFLI_sync.py +108 -0
  27. qcodespp/instrument_drivers/ZI/ZIUHFLI.py +2179 -0
  28. qcodespp/instrument_drivers/ZI/__init__.py +1 -0
  29. qcodespp/instrument_drivers/__init__.py +0 -0
  30. qcodespp/instrument_drivers/cryogenic/CryogenicSMS120C.py +599 -0
  31. qcodespp/instrument_drivers/cryogenic/__init__.py +0 -0
  32. qcodespp/instrument_drivers/instrument_mocks.py +379 -0
  33. qcodespp/instrument_drivers/multiplexer_instrument.py +287 -0
  34. qcodespp/instrument_drivers/national_instruments/PXI_4461.py +451 -0
  35. qcodespp/instrument_drivers/national_instruments/PXI_4462.py +290 -0
  36. qcodespp/instrument_drivers/national_instruments/PXI_6259.py +436 -0
  37. qcodespp/instrument_drivers/national_instruments/PXI_6733.py +230 -0
  38. qcodespp/instrument_drivers/national_instruments/PXI_6733_e.py +243 -0
  39. qcodespp/instrument_drivers/national_instruments/__init__.py +0 -0
  40. qcodespp/instrument_drivers/oxford/__init__.py +0 -0
  41. qcodespp/instrument_drivers/oxford/mercuryiPS_serial.py +658 -0
  42. qcodespp/instrument_drivers/oxford/triton.py +434 -0
  43. qcodespp/instrument_drivers/tektronix/Keithley_2000_Scan.py +65 -0
  44. qcodespp/instrument_drivers/tektronix/Keithley_2182a.py +190 -0
  45. qcodespp/instrument_drivers/tektronix/Keithley_2400.py +158 -0
  46. qcodespp/instrument_drivers/tektronix/Keithley_2450.py +242 -0
  47. qcodespp/instrument_drivers/tektronix/Keithley_2700.py +397 -0
  48. qcodespp/instrument_drivers/tektronix/Keithley_6500.py +161 -0
  49. qcodespp/instrument_drivers/tektronix/__init__.py +0 -0
  50. qcodespp/instrument_drivers/yokogawa/GS200.py +513 -0
  51. qcodespp/instrument_drivers/yokogawa/__init__.py +0 -0
  52. qcodespp/loops.py +1342 -0
  53. qcodespp/measure.py +310 -0
  54. qcodespp/parameters.py +311 -0
  55. qcodespp/plotting/RemotePlot.py +469 -0
  56. qcodespp/plotting/RemotePlotClient.py +367 -0
  57. qcodespp/plotting/RemoteQtPlotWidgets.py +871 -0
  58. qcodespp/plotting/__init__.py +0 -0
  59. qcodespp/plotting/analysis_tools.py +195 -0
  60. qcodespp/plotting/colors.py +135 -0
  61. qcodespp/plotting/offline/__init__.py +0 -0
  62. qcodespp/plotting/offline/datatypes.py +999 -0
  63. qcodespp/plotting/offline/design.py +906 -0
  64. qcodespp/plotting/offline/design.ui +1578 -0
  65. qcodespp/plotting/offline/editor.py +2966 -0
  66. qcodespp/plotting/offline/filters.py +561 -0
  67. qcodespp/plotting/offline/fits.py +1171 -0
  68. qcodespp/plotting/offline/helpers.py +288 -0
  69. qcodespp/plotting/offline/iconGadget.png +0 -0
  70. qcodespp/plotting/offline/main.py +55 -0
  71. qcodespp/plotting/offline/popupwindows.py +1848 -0
  72. qcodespp/plotting/offline/qcodes_pp_extension.py +328 -0
  73. qcodespp/plotting/offline/sidebars.py +1108 -0
  74. qcodespp/station.py +290 -0
  75. qcodespp/utils/__init__.py +0 -0
  76. qcodespp/utils/helpers.py +618 -0
  77. qcodespp/utils/visa_helpers.py +61 -0
  78. qcodespp/version.py +12 -0
  79. qcodespp-0.1.0.dist-info/METADATA +91 -0
  80. qcodespp-0.1.0.dist-info/RECORD +82 -0
  81. qcodespp-0.1.0.dist-info/WHEEL +4 -0
  82. qcodespp-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,469 @@
1
+ import subprocess
2
+ import threading
3
+ import os
4
+
5
+ import numpy as np
6
+ import zmq
7
+ import json
8
+ from uuid import uuid4
9
+
10
+ from qcodespp.data.data_set import DataSetPP
11
+ from qcodespp.data.data_array import DataArray
12
+ from qcodespp.utils.helpers import NumpyJSONEncoder
13
+ from qcodespp.parameters import Parameter
14
+
15
+ def live_plot(*args,data_set=None, data_items=None):
16
+ """
17
+ Entry point for live plotting of qcodespp data.
18
+
19
+ Args:
20
+ *args (DataSetPP, DataArray, Parameter, list, tuple): Positional arguments can be:
21
+ - ``DataSetPP``: The dataset to link to the live plot.
22
+ - ``DataArray`` or ``Parameter``: The data items to plot.
23
+ - A list or tuple of ``DataArray`` or ``Parameter`` objects to plot.
24
+ data_set (``DataSetPP``, optional): The ``DataSetPP`` to link to the live plot.
25
+ If not provided, it will try to use the default dataset.
26
+ If no data_set, one can add items to the plot, but the data will not be tracked.
27
+ data_items (Sequence[``DataArray``, ``Parameter``], optional): List of ``DataArray``
28
+ or ``Parameter`` objects to plot. If not provided, nothing will be plotted initially,
29
+ the user can use ``Plot.add()`` later.
30
+
31
+ Returns:
32
+ The ``Plot`` instance.
33
+ """
34
+
35
+ if data_items is None:
36
+ data_items = []
37
+
38
+ for arg in args:
39
+ if isinstance(arg, DataSetPP):
40
+ data_set = arg
41
+ elif isinstance(arg, (DataArray, Parameter)):
42
+ data_items.append(arg)
43
+ elif isinstance(arg, (list, tuple)):
44
+ data_items.extend(arg)
45
+
46
+ plot = Plot()
47
+ if data_set is None and DataSetPP.default_dataset is not None:
48
+ data_set = DataSetPP.default_dataset
49
+ if data_set:
50
+ data_set.publisher=plot
51
+ if data_items:
52
+ new_items=[]
53
+ for item in data_items:
54
+ if isinstance(item, Parameter) and not data_set:
55
+ raise ValueError('Parameters only accepted to data_items if a data_set is also provided.')
56
+ elif isinstance(item, Parameter):
57
+ for array in data_set.arrays:
58
+ if item.full_name in array:
59
+ new_items.append(data_set.arrays[array])
60
+ elif isinstance(item, DataArray):
61
+ new_items.append(item)
62
+ if not data_set:
63
+ try: # Try ONE more time to link some kind of data set to the plot.
64
+ item.data_set.publisher = plot
65
+ except:
66
+ pass
67
+ else:
68
+ raise TypeError('data_items must be either DataArray or Parameter objects, not %s.' % type(item))
69
+ plot.add_multiple(*new_items)
70
+
71
+ return plot
72
+
73
+ class ControlListener(threading.Thread):
74
+ """
75
+ ListenToClientTask
76
+ """
77
+ def __init__(self, client_ready_event=None, port=8876):
78
+ self.client_ready_event = client_ready_event
79
+ self.context = zmq.Context()
80
+ self.socket = self.context.socket(zmq.SUB)
81
+
82
+ self.port = self.socket.bind_to_random_port('tcp://*',
83
+ min_port=port,
84
+ max_port=port+500,
85
+ max_tries=500)
86
+
87
+ self.socket.setsockopt(zmq.SUBSCRIBE, b'')
88
+
89
+ self.poller = zmq.Poller()
90
+ self.poller.register(self.socket, zmq.POLLIN)
91
+
92
+ threading.Thread.__init__(self)
93
+
94
+ self.running = True
95
+
96
+ def run(self):
97
+ while self.running:
98
+ socks = dict(self.poller.poll(1000))
99
+ if socks.get(self.socket) == zmq.POLLIN:
100
+ try:
101
+ msg = self.socket.recv_json()
102
+ ready = msg.get('client_ready', None)
103
+ if ready is True:
104
+ self.client_ready_event.set()
105
+ else:
106
+ pass
107
+ # print(msg)
108
+ except Exception:
109
+ print('ups ups ups')
110
+
111
+ self.socket.close()
112
+ self.context.term()
113
+
114
+
115
+ class Plot():
116
+ """
117
+ Class to create live plot instances.
118
+
119
+ Most methods of this class should not be called directly; only add(), add_multiple(), clear() and close()
120
+ should be used by the user.
121
+
122
+ Args:
123
+ title (str, optional): Title of the plot window.
124
+ name (str, optional): Name of the plot instance. If not provided, a random UUID will be used.
125
+ """
126
+
127
+ context = zmq.Context()
128
+ socket = context.socket(zmq.PUB)
129
+
130
+ port = 8876
131
+ port = socket.bind_to_random_port('tcp://*',
132
+ min_port=port,
133
+ max_port=port+20,
134
+ max_tries=100)
135
+ encoding = 'utf-8'
136
+
137
+ def __init__(self, title=None, name=None):
138
+ name = name or uuid4().hex
139
+ topic = 'qcodes.plot.'+name
140
+ self.topic = topic
141
+ self.metadata = {}
142
+ self.data_uuid = uuid4().hex
143
+
144
+ self.client_ready_event = threading.Event()
145
+ self.client_ready_event.clear()
146
+
147
+ self.control_task = ControlListener(self.client_ready_event)
148
+ self.control_task.start()
149
+ self.control_port = self.control_task.port
150
+
151
+ self.new_client()
152
+
153
+ ret = self.client_ready_event.wait(30)
154
+ if ret == False:
155
+ print('timeout for plot window.')
156
+ self.client_ready_event.clear()
157
+
158
+ self.set_title(title)
159
+
160
+ def publish(self, data, uuid=None):
161
+ jdata = json.dumps(data, cls=NumpyJSONEncoder)
162
+ uuid = uuid or ''
163
+ self.socket.send_multipart([self.topic.encode(self.encoding),
164
+ uuid.encode(self.encoding),
165
+ jdata.encode(self.encoding)])
166
+
167
+ def publish_data(self, data, uuid, meta, arrays):
168
+ jdata = json.dumps(data)
169
+ uuid = uuid or ''
170
+ jmeta = json.dumps(meta)
171
+ self.socket.send_multipart([self.topic.encode(self.encoding),
172
+ uuid.encode(self.encoding),
173
+ jdata.encode(self.encoding),
174
+ jmeta.encode(self.encoding),
175
+ *arrays])
176
+
177
+ def add_metadata(self, new_metadata, uuid=None):
178
+ data = {'metadata': new_metadata}
179
+ self.publish(data, uuid)
180
+
181
+ def store(self, loop_indices, ids_values, uuid):
182
+ data = {'data': {'values': ids_values,
183
+ 'indices': loop_indices}}
184
+ self.publish(data, uuid)
185
+
186
+ def save_metadata(self, metadata, uuid=None):
187
+ self.add_metadata(metadata, uuid)
188
+
189
+ def finalize(self, uuid=None):
190
+ self.publish({'finalize': True}, uuid)
191
+
192
+ def new_client(self, name=None):
193
+ this_dir, this_filename = os.path.split(__file__)
194
+ client = os.path.join(this_dir, 'RemotePlotClient.py')
195
+ args = ['python',
196
+ client,
197
+ self.topic,
198
+ str(self.port),
199
+ str(self.control_port)]
200
+
201
+ print(' '.join(args))
202
+
203
+ DETACHED_PROCESS = 0x00000008
204
+
205
+ subprocess.Popen(args, creationflags=DETACHED_PROCESS)
206
+
207
+ def clear(self):
208
+ self.publish({'clear_plot': True})
209
+
210
+ def add_multiple(self,*z_params):
211
+ """Add multiple ``DataArray`` s to the ``Plot``.
212
+
213
+ Args:
214
+ *z_params (Sequence [DataArray]): DataArrays to be added to the Plot.
215
+ Each DataArray is added to a separate subplot.
216
+ """
217
+ for i,z_param in enumerate(z_params):
218
+ self.add(z_param,subplot=i) #title=z_param.full_name,name=z_param.name,
219
+
220
+ def add(self, *args, x=None, y=None, z=None,
221
+ subplot=0, name=None, title=None, position=None,
222
+ relativeto=None, xlabel=None, ylabel=None, zlabel=None,
223
+ xunit=None, yunit=None, zunit=None, silent=True,linecuts=False,
224
+ symbol=None,#color=None, width=None, pen=False, brush=None,
225
+ size=None,# antialias=None,
226
+ **kwargs):
227
+ """
228
+ Add a trace to the plot.
229
+
230
+ Args:
231
+ *args (DataArray): positional arguments, can be:
232
+ - ``y`` or ``z``: specify just the 1D or 2D data independent parameter, with the setpoint
233
+ axis or axes implied from the DataSetPP setpoints.
234
+ - ``x, y`` or ``x, y, z``: specify all axes of the data.
235
+ x (DataArray, optional): x-axis data.
236
+ y (DataArray, optional): y-axis data.
237
+ z (DataArray, optional): z-axis data.
238
+ subplot (int, optional): Subplot index to add the trace to. Defaults to 0.
239
+ name (str, optional): Name of the trace. If not provided, the name of the DataArray will be used.
240
+ title (str, optional): Title of the trace. If not provided, the name of the DataArray will be used.
241
+ position (str): Position of the subplot in the plot window. Options are 'bottom', 'top', 'left', 'right', 'above', or 'below'.
242
+ relativeto (str, optional): Position relative to which the subplot should be placed.
243
+ xlabel (str, optional): Label for the x-axis. If not provided, the label of the DataArray will be used.
244
+ ylabel (str, optional): Label for the y-axis. If not provided, the label of the DataArray will be used.
245
+ zlabel (str, optional): Label for the z-axis. If not provided, the label of the DataArray will be used.
246
+ xunit (str, optional): Unit for the x-axis. If not provided, the unit of the DataArray will be used.
247
+ yunit (str, optional): Unit for the y-axis. If not provided, the unit of the DataArray will be used.
248
+ zunit (str, optional): Unit for the z-axis. If not provided, the unit of the DataArray will be used.
249
+ silent (bool, optional): If True, do not wait for the client to be ready. Defaults to True.
250
+ linecuts (bool, optional): If True, plot line cuts instead of a 2D image. Defaults to False.
251
+ symbol (str, optional): Symbol to use for the trace. Defaults to None.
252
+ size (int, optional): Size of the symbol. Defaults to None.
253
+ """
254
+
255
+ if x is not None:
256
+ kwargs['x'] = x
257
+ if y is not None:
258
+ kwargs['y'] = y
259
+ if z is not None:
260
+ kwargs['z'] = z
261
+
262
+ kwargs['xlabel'] = xlabel
263
+ kwargs['ylabel'] = ylabel
264
+ kwargs['zlabel'] = zlabel
265
+ kwargs['xunit'] = xunit
266
+ kwargs['yunit'] = yunit
267
+ kwargs['zunit'] = zunit
268
+ kwargs['name'] = name
269
+
270
+ self.expand_trace(args, kwargs)
271
+
272
+ x = kwargs.get('x', None)
273
+ y = kwargs.get('y', None)
274
+ z = kwargs.get('z', None)
275
+
276
+ uuid = None
277
+
278
+ arguments = {'subplot': subplot,
279
+ 'title': title,
280
+ 'position': position,
281
+ 'relativeto': relativeto,
282
+ 'linecuts':linecuts,
283
+ 'symbol': symbol,
284
+ 'size': size}#,
285
+ # 'color': color,
286
+ # 'width': width,
287
+ # 'pen': pen,
288
+ # 'brush': brush,
289
+ # 'size': size,
290
+ # 'antialias': antialias}
291
+
292
+ meta = []
293
+ arrays = []
294
+
295
+ uuid = self.data_uuid
296
+
297
+ snap_name = None
298
+
299
+ for arr_name, arr in zip(['x', 'y', 'z'], [x, y, z]):
300
+
301
+
302
+ shape = None
303
+ location = None
304
+ array_id = None
305
+ unit = None
306
+ label = None
307
+
308
+ if arr is not None:
309
+ if isinstance(arr, DataArray):
310
+ snap = arr.snapshot()
311
+ uuid = arr.data_set.uuid
312
+
313
+ location = getattr(arr.data_set, 'location', None)
314
+ label = snap.get('label', None)
315
+ if snap.get('unit',None) is not None:
316
+ unit = snap.get('unit', None)
317
+ elif snap.get('units', None) is not None:
318
+ unit = snap.get('units',None)
319
+ snap_name = snap.get('name', None)
320
+ shape = snap.get('shape', None)
321
+ array_id = arr.array_id
322
+ else:
323
+ array_id = uuid4().hex
324
+
325
+
326
+ unit = kwargs.get('%sunit'%arr_name, None) or unit
327
+ label = kwargs.get('%slabel'%arr_name, None) or label
328
+
329
+ arguments['%s_info'%arr_name] = {}
330
+ arguments['%s_info'%arr_name]['location'] = location
331
+ arguments['%s_info'%arr_name]['label'] = label
332
+ arguments['%s_info'%arr_name]['unit'] = unit
333
+ arguments['%s_info'%arr_name]['shape'] = shape
334
+ arguments['%s_info'%arr_name]['name'] = snap_name or name
335
+ arguments['%s_info'%arr_name]['array_id'] = array_id
336
+ arguments['name'] = name or snap_name
337
+
338
+ for arr_name, arr in zip(['x', 'y', 'z'], [x, y, z]):
339
+ if arr is not None:
340
+ if isinstance(arr, DataArray):
341
+ ndarr = arr.ndarray
342
+ if isinstance(arr, np.ndarray):
343
+ ndarr = arr
344
+ else:
345
+ try:
346
+ ndarr = np.array(arr)
347
+ except:
348
+ continue
349
+
350
+ if (~np.isnan(ndarr)).any():
351
+ arrays.append(ndarr)
352
+ arguments['%s_info'%arr_name]['shape'] = ndarr.shape
353
+ arguments['%s_info'%arr_name]['name']
354
+
355
+ meta.append({'array_id': arguments['%s_info'%arr_name]['array_id'],
356
+ 'shape': ndarr.shape,
357
+ 'dtype': str(ndarr.dtype)})
358
+
359
+ if len(arrays) > 0:
360
+ self.publish_data({'add_plot': arguments},
361
+ uuid, meta, arrays)
362
+ else:
363
+ self.publish({'add_plot': arguments}, uuid)
364
+
365
+ if not silent:
366
+ # self.client_ready_event.clear()
367
+ # return
368
+ ret = self.client_ready_event.wait(30)
369
+ if ret == False:
370
+ print('plot timed out!')
371
+ self.client_ready_event.clear()
372
+
373
+ def expand_trace(self, args, kwargs):
374
+ """
375
+ Complete the x, y (and possibly z) data definition for a trace.
376
+
377
+ Also modifies kwargs in place so that all the data needed to fully specify the
378
+ trace is present (ie either x and y or x and y and z)
379
+
380
+ Both ``__init__`` (for the first trace) and the ``add`` method support multiple
381
+ ways to specify the data in the trace:
382
+
383
+ As args:
384
+ - ``add(y)`` or ``add(z)`` specify just the main 1D or 2D data, with the setpoint
385
+ axis or axes implied.
386
+ - ``add(x, y)`` or ``add(x, y, z)`` specify all axes of the data.
387
+ And as kwargs:
388
+ - ``add(x=x, y=y, z=z)`` you specify exactly the data you want on each axis.
389
+ Any but the last (y or z) can be omitted, which allows for all of the same
390
+ forms as with args, plus x and z or y and z, with just one axis implied from
391
+ the setpoints of the z data.
392
+
393
+ This method takes any of those forms and converts them into a complete set of
394
+ kwargs, containing all of the explicit or implied data to be used in plotting this trace.
395
+
396
+ Args:
397
+ args (Tuple[DataArray]): positional args, as passed to either ``__init__`` or ``add``
398
+ kwargs (Dict(DataArray]): keyword args, as passed to either ``__init__`` or ``add``.
399
+ kwargs may contain non-data items in keys other than x, y, and z.
400
+
401
+ Raises:
402
+ ValueError: if the shape of the data does not match that of args
403
+ ValueError: if the data is provided twice
404
+ """
405
+ # TODO(giulioungaretti): replace with an explicit version:
406
+ # return the new kwargs instead of modifying in place
407
+ # TODO this should really be a static method
408
+ if args:
409
+ if hasattr(args[-1][0], '__len__'):
410
+ # 2D (or higher... but ignore this for now)
411
+ # this test works for both numpy arrays and bare sequences
412
+ axletters = 'xyz'
413
+ ndim = 2
414
+ else:
415
+ axletters = 'xy'
416
+ ndim = 1
417
+
418
+ if len(args) not in (1, len(axletters)):
419
+ raise ValueError('{}D data needs 1 or {} unnamed args'.format(
420
+ ndim, len(axletters)))
421
+
422
+ arg_axletters = axletters[-len(args):]
423
+
424
+ for arg, arg_axletters in zip(args, arg_axletters):
425
+ # if arg_axletters in kwargs:
426
+ # raise ValueError(arg_axletters + ' data provided twice')
427
+ kwargs[arg_axletters] = arg
428
+
429
+ # reset axletters, we may or may not have found them above
430
+ axletters = 'xyz' if 'z' in kwargs else 'xy'
431
+ main_data = kwargs.get(axletters[-1], None)
432
+
433
+ if hasattr(main_data, 'set_arrays'):
434
+ num_axes = len(axletters) - 1
435
+ # things will probably fail if we try to plot arrays of the
436
+ # wrong dimension... but we'll give it a shot anyway.
437
+ set_arrays = main_data.set_arrays[-num_axes:]
438
+ # for 2D: y is outer loop, which is earlier in set_arrays,
439
+ # and x is the inner loop... is this the right convention?
440
+ # Merlin: Not in my view, I step on x-axis and do many
441
+ # y-sweeps, thus removed this reversing here.
442
+ set_axletters = axletters[:-1]
443
+ for axletter, set_array in zip(set_axletters, set_arrays):
444
+ if axletter not in kwargs:
445
+ kwargs[axletter] = set_array
446
+
447
+ def set_title(self, title):
448
+ self.publish({'set_title': title})
449
+
450
+ def set_cmap(self, cmap):
451
+ self.publish({'set_cmap': cmap})
452
+
453
+ def save(self, filename=None, subplot=None):
454
+ self.publish({'save_screenshot': {'filename': str(filename), 'subplot': subplot}})
455
+ # print('Should save a screenshot of the plot now')
456
+
457
+ def set_xlabel(self, label, subplot=0):
458
+ print('Should set the x-label of a subplot now')
459
+
460
+ def set_ylabel(self, label, subplot=0):
461
+ print('Should set the y-label of a subplot now')
462
+
463
+ def set_geometry(self, height, width, x0, y0):
464
+ # like other qt takes it:
465
+ print('Should set the geometry of the window now')
466
+
467
+ def close(self):
468
+ self.publish({'close_client': True})
469
+ print('Should close the plot window now')