Adding support for plotting |Z| on logarithmic scale

pull/377/head
Roel Jordans 2021-02-21 21:48:04 +01:00
rodzic c6878fce8f
commit 9c7f6a80f7
2 zmienionych plików z 71 dodań i 12 usunięć

Wyświetl plik

@ -44,6 +44,7 @@ class FrequencyChart(Chart):
fixedValues = False
logarithmicX = False
logarithmicY = False
leftMargin = 30
rightMargin = 20
@ -132,6 +133,23 @@ class FrequencyChart(Chart):
self.y_menu.addAction(self.action_set_fixed_maximum)
self.y_menu.addAction(self.action_set_fixed_minimum)
if self.logarithmicYAllowed(): # This only works for some plot types
self.y_menu.addSeparator()
vertical_mode_group = QtWidgets.QActionGroup(self.y_menu)
self.action_set_linear_y = QtWidgets.QAction("Linear")
self.action_set_linear_y.setCheckable(True)
self.action_set_logarithmic_y = QtWidgets.QAction("Logarithmic")
self.action_set_logarithmic_y.setCheckable(True)
vertical_mode_group.addAction(self.action_set_linear_y)
vertical_mode_group.addAction(self.action_set_logarithmic_y)
self.action_set_linear_y.triggered.connect(
lambda: self.setLogarithmicY(False))
self.action_set_logarithmic_y.triggered.connect(
lambda: self.setLogarithmicY(True))
self.action_set_linear_y.setChecked(True)
self.y_menu.addAction(self.action_set_linear_y)
self.y_menu.addAction(self.action_set_logarithmic_y)
self.menu.addMenu(self.x_menu)
self.menu.addMenu(self.y_menu)
self.menu.addSeparator()
@ -178,12 +196,21 @@ class FrequencyChart(Chart):
self.fixedValues = False
self.y_action_automatic.setChecked(True)
self.y_action_fixed_span.setChecked(False)
if fixed_values and self.minDisplayValue <= 0:
self.minDisplayValue = 0.01
self.update()
def setLogarithmicX(self, logarithmic: bool):
self.logarithmicX = logarithmic
self.update()
def setLogarithmicY(self, logarithmic: bool):
self.logarithmicY = logarithmic and self.logarithmicYAllowed()
self.update()
def logarithmicYAllowed(self) -> bool:
return False
def setMinimumFrequency(self):
min_freq_str, selected = QtWidgets.QInputDialog.getText(
self, "Start frequency",
@ -217,6 +244,8 @@ class FrequencyChart(Chart):
return
if not (self.fixedValues and min_val >= self.maxDisplayValue):
self.minDisplayValue = min_val
if self.logarithmicY and min_val <= 0:
self.minDisplayValue = 0.01
if self.fixedValues:
self.update()
@ -239,6 +268,9 @@ class FrequencyChart(Chart):
self.action_automatic.setChecked(True)
self.logarithmicX = False
self.action_set_linear_x.setChecked(True)
self.logarithmicY = False
if self.logarithmicYAllowed():
self.action_set_linear_y.setChecked(True)
self.update()
def getXPosition(self, d: Datapoint) -> int:
@ -585,6 +617,11 @@ class FrequencyChart(Chart):
new_chart.setLogarithmicX(self.logarithmicX)
new_chart.action_set_logarithmic_x.setChecked(self.logarithmicX)
new_chart.action_set_linear_x.setChecked(not self.logarithmicX)
new_chart.setLogarithmicY(self.logarithmicY)
if self.logarithmicYAllowed():
new_chart.action_set_logarithmic_y.setChecked(self.logarithmicY)
new_chart.action_set_linear_y.setChecked(not self.logarithmicY)
return new_chart
def keyPressEvent(self, a0: QtGui.QKeyEvent) -> None:

Wyświetl plik

@ -82,7 +82,10 @@ class MagnitudeZChart(FrequencyChart):
maxValue = self.maxDisplayValue
minValue = self.minDisplayValue
self.maxValue = maxValue
self.minValue = minValue
if self.logarithmicY and minValue <= 0:
self.minValue = 0.01
else:
self.minValue = minValue
else:
# Find scaling
minValue = 100
@ -107,7 +110,10 @@ class MagnitudeZChart(FrequencyChart):
minValue = mag
minValue = 10*math.floor(minValue/10)
if self.logarithmicY and minValue <= 0:
minValue = 0.01
self.minValue = minValue
maxValue = 10*math.ceil(maxValue/10)
self.maxValue = maxValue
@ -118,17 +124,21 @@ class MagnitudeZChart(FrequencyChart):
target_ticks = math.floor(self.chartHeight / 60)
for i in range(target_ticks):
val = minValue + (i / target_ticks) * span
y = self.topMargin + round((self.maxValue - val) / self.span * self.chartHeight)
for i in range(1, target_ticks):
val = minValue + (i / target_ticks) * self.span
if self.logarithmicY:
y = self.topMargin + (self.maxValue - val) / self.span * self.chartHeight
val = self.valueAtPosition(y)[0]
else:
y = self.topMargin + round((self.maxValue - val) / self.span * self.chartHeight)
qp.setPen(self.textColor)
if val != minValue:
digits = max(0, min(2, math.floor(3 - math.log10(abs(val)))))
if digits == 0:
vswrstr = str(round(val))
else:
vswrstr = str(round(val, digits))
qp.drawText(3, y + 3, vswrstr)
digits = max(0, min(2, math.floor(5 - math.log10(abs(val)))))
if digits == 0:
vswrstr = str(round(val))
else:
vswrstr = str(round(val, digits))
qp.drawText(3, y + 3, vswrstr)
qp.setPen(QtGui.QPen(self.foregroundColor))
qp.drawLine(self.leftMargin - 5, y, self.leftMargin + self.chartWidth, y)
@ -146,20 +156,32 @@ class MagnitudeZChart(FrequencyChart):
def getYPosition(self, d: Datapoint) -> int:
mag = self.magnitude(d)
if self.logarithmicY and mag == 0:
return self.topMargin - self.chartHeight
if math.isfinite(mag):
if self.logarithmicY:
span = math.log(self.maxValue) - math.log(self.minValue)
return self.topMargin + round((math.log(self.maxValue) - math.log(mag)) / span * self.chartHeight)
return self.topMargin + round((self.maxValue - mag) / self.span * self.chartHeight)
else:
return self.topMargin
def valueAtPosition(self, y) -> List[float]:
absy = y - self.topMargin
val = -1 * ((absy / self.chartHeight * self.span) - self.maxValue)
if self.logarithmicY:
span = math.log(self.maxValue) - math.log(self.minValue)
val = math.exp(math.log(self.maxValue) - absy * span / self.chartHeight)
else:
val = self.maxValue - (absy / self.chartHeight * self.span)
return [val]
@staticmethod
def magnitude(p: Datapoint) -> float:
return abs(p.impedance())
def logarithmicYAllowed(self) -> bool:
return True;
def copy(self):
new_chart: LogMagChart = super().copy()
new_chart.span = self.span