kopia lustrzana https://github.com/NanoVNA-Saver/nanovna-saver
Adding support for plotting |Z| on logarithmic scale
rodzic
c6878fce8f
commit
9c7f6a80f7
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
Ładowanie…
Reference in New Issue