def test_calculate_bins(self): kwargs = { "comp_x": 10, "comp_y": 20 } self.assertEqual(((10, 5), None), mf.calculate_bin_counts( self.unsorted_data, **kwargs )) self.assert_all_equal( lambda data: mf.calculate_bin_counts(data, **kwargs), self.all_data )
def test_bad_inputs(self): self.assertRaises( ValueError, lambda: mf.calculate_bin_counts(self.unsorted_data, 0, 0)) self.assertRaises( ValueError, lambda: mf.calculate_bin_counts(self.unsorted_data, 10, -1)) self.assertRaises( ValueError, lambda: mf.calculate_bin_counts(self.unsorted_data, 1, 1, min_count=20, max_count=10))
def test_max_count(self): kwargs = { "comp_x": 5, "comp_y": 10, "max_count": 15 } self.assertEqual( ((15, 10), "Bin count exceeded maximum value of 15. Adjustment " "made."), mf.calculate_bin_counts(self.unsorted_data, **kwargs)) self.assert_all_equal( lambda data: mf.calculate_bin_counts(data, **kwargs), self.all_data )
def test_sorted_count(self): kwargs = { "comp_x": 10, "comp_y": 10, "data_sorted": True } expected_x = int(math.fabs(self.unsorted_data[0][0] - self.unsorted_data[0][-1]) / 10) expected_y = int(math.fabs(self.unsorted_data[1][0] - self.unsorted_data[1][-1]) / 10) if not expected_x: expected_x = 1 if not expected_y: expected_y = 1 self.assertEqual(((expected_x, expected_y), None), mf.calculate_bin_counts(self.unsorted_data, **kwargs)) self.assert_all_equal( lambda data: mf.calculate_bin_counts(data, **kwargs), [self.asc_sorted_data, self.desc_sorted_data] )
def test_return_type(self): # bin counts should always be integers n = 10 for _ in range(n): kwargs = { "data": [ [random.random() for _ in range(20)], [random.random() for _ in range(20)] ], "comp_x": random.random(), "comp_y": random.random(), "min_count": random.uniform(5.5, 15.5), "max_count": random.uniform(25.5, 35.5), "data_sorted": random.random() > 0.5 } (x_bins, y_bins), _ = mf.calculate_bin_counts(**kwargs) self.assertIsInstance(x_bins, int) self.assertIsInstance(y_bins, int)
def on_draw(self): """Draw method for matplotlib. """ # Values for zoom x_min, x_max = self.axes.get_xlim() y_min, y_max = self.axes.get_ylim() x_data = self.__x_data y_data = self.__y_data # Transpose if self.transpose_axes: x_data, y_data = y_data, x_data # Always transpose data if checked. if not self.__transposed: self.__transposed = True self.measurement.selector.transpose(True) # Switch axes names self.name_x_axis, self.name_y_axis = (self.name_y_axis, self.name_x_axis) # Switch min & max values x_min, x_max, y_min, y_max = y_min, y_max, x_min, x_max # Switch inverts self.invert_X, self.invert_Y = self.invert_Y, self.invert_X if not self.transpose_axes and self.__transposed: self.__transposed = False self.measurement.selector.transpose(False) # Switch axes names self.name_x_axis, self.name_y_axis \ = self.name_y_axis, self.name_x_axis # Switch min & max values x_min, x_max, y_min, y_max = y_min, y_max, x_min, x_max # Switch inverts self.invert_X, self.invert_Y = self.invert_Y, self.invert_X # Clear old stuff self.axes.clear() # Check bin counts and axes ranges # If bin count too high -> it will crash the program, use 3500 # If 10 000, tofe_65 example can have compression as 1, but REALLY # slow. Usually, bin count around 8000 if self.axes_range_mode == 1: # Manual axe range mode bin_counts, msg = mf.calculate_bin_counts( self.axes_range, self.compression_x, self.compression_y, max_count=MatplotlibHistogramWidget.MAX_BIN_COUNT) axes_range = self.axes_range else: # Automatic mode bin_counts, msg = mf.calculate_bin_counts( [x_data, y_data], self.compression_x, self.compression_y, max_count=MatplotlibHistogramWidget.MAX_BIN_COUNT) axes_range = None if msg is not None: # Message is displayed when bin count was too high and had to be # lowered QtWidgets.QMessageBox.warning(self.parent, "Warning", msg, QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Ok) colormap = cm.get_cmap(self.color_scheme.value) self.axes.hist2d(x_data, y_data, bins=bin_counts, norm=LogNorm(), range=axes_range, cmap=colormap) self.__on_draw_legend() if 0.09 < x_max < 1.01: # This works.. x_min, x_max = self.axes.get_xlim() if 0.09 < y_max < 1.01: # or self.axes_range_mode y_min, y_max = self.axes.get_ylim() # Change zoom limits if compression factor was changed (or new graph). if not self.__range_mode_automated and self.axes_range_mode == 0 \ or self.axes_range_mode == 1: # self.__range_mode_automated and self.axes_range_mode == 1 tx_min, tx_max = self.axes.get_xlim() ty_min, ty_max = self.axes.get_ylim() # If user has zoomed the graph, change the home position to new max. # Else reset the graph to new ranges and clear zoom levels. if self.mpl_toolbar._views: self.mpl_toolbar._views[0][0] = (tx_min, tx_max, ty_min, ty_max) else: x_min, x_max = tx_min, tx_max y_min, y_max = ty_min, ty_max self.mpl_toolbar.update() self.__range_mode_automated = self.axes_range_mode == 0 # print(self.axes.get_xlim()) # Set limits accordingly self.axes.set_ylim([y_min, y_max]) self.axes.set_xlim([x_min, x_max]) self.measurement.draw_selection() # Invert axis if self.invert_Y and not self.__inverted_Y: self.axes.set_ylim(self.axes.get_ylim()[::-1]) self.__inverted_Y = True elif not self.invert_Y and self.__inverted_Y: self.axes.set_ylim(self.axes.get_ylim()[::-1]) self.__inverted_Y = False if self.invert_X and not self.__inverted_X: self.axes.set_xlim(self.axes.get_xlim()[::-1]) self.__inverted_X = True elif not self.invert_X and self.__inverted_X: self.axes.set_xlim(self.axes.get_xlim()[::-1]) self.__inverted_X = False # [::-1] is elegant reverse. Slice sequence with step of -1. # http://stackoverflow.com/questions/3705670/ # best-way-to-create-a-reversed-list-in-python # self.axes.set_title('ToF Histogram\n\n') self.axes.set_ylabel(self.name_y_axis.title()) self.axes.set_xlabel(self.name_x_axis.title()) # Remove axis ticks and draw self.remove_axes_ticks() self.canvas.draw()
def test_empty_list(self): self.assertEqual(((1, 1), None), mf.calculate_bin_counts([[1], []], 1, 1))