-
Notifications
You must be signed in to change notification settings - Fork 55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added 20*log10(mag) for Pyqtgraph #395
Changes from 16 commits
fc27f24
a1c566a
3767bb0
af3a0cf
0091ebb
e50f25c
738a4fd
f4c81e7
6a7c1b0
98a7b31
d28f399
e8ce42b
d523cee
f8260f0
875fc75
9fa3772
d4ad24b
a5638bc
41dad4d
d5c1ed2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -184,8 +184,15 @@ def plot(self, plotItem: PlotItem) -> None: | |
plotItem.plotDataType = PlotDataType.scatter1d | ||
elif len(plotItem.data) == 3: | ||
plotItem.plotDataType = PlotDataType.scatter2d | ||
|
||
if plotItem.plotDataType in [PlotDataType.scatter1d, PlotDataType.line1d]: | ||
|
||
#If the Complex Representation is correct | ||
if self.complexRepresentation == ComplexRepresentation.log_MagAndPhase: | ||
|
||
#Switch the 1d plots to the logarithmic variation | ||
if plotItem.plotDataType == PlotDataType.scatter1d and plotItem.subPlot == 0: plotItem.plotDataType = PlotDataType.log10_scatter1d | ||
if plotItem.plotDataType == PlotDataType.line1d and plotItem.subPlot == 0: plotItem.plotDataType = PlotDataType.log10_line1d | ||
|
||
if plotItem.plotDataType in [PlotDataType.scatter1d, PlotDataType.line1d,PlotDataType.log10_line1d,PlotDataType.log10_scatter1d]: | ||
self._1dPlot(plotItem) | ||
elif plotItem.plotDataType == PlotDataType.grid2d: | ||
self._colorPlot(plotItem) | ||
|
@@ -212,11 +219,22 @@ def _1dPlot(self, plotItem: PlotItem) -> None: | |
return subPlot.plot.plot(x.flatten(), y.flatten(), name=name, | ||
pen=mkPen(color, width=1), symbol=symbol, symbolBrush=color, | ||
symbolPen=None, symbolSize=symbolSize) | ||
else: | ||
elif plotItem.plotDataType == PlotDataType.log10_line1d: | ||
name = plotItem.labels[-1] if isinstance(plotItem.labels, list) else '' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This syntax is cool, but it makes it harder to read compared to a normal if else block |
||
return subPlot.plot.plot(x.flatten(), 20*np.log10(y.flatten()), name=name, | ||
pen=mkPen(color, width=1), symbol=symbol, symbolBrush=color, | ||
symbolPen=None, symbolSize=symbolSize) | ||
elif plotItem.plotDataType == PlotDataType.scatter1d: | ||
name = plotItem.labels[-1] if isinstance(plotItem.labels, list) else '' | ||
return subPlot.plot.plot(x.flatten(), y.flatten(), name=name, | ||
pen=None, symbol=symbol, symbolBrush=color, | ||
symbolPen=None, symbolSize=symbolSize) | ||
#instance of PlotDataType.log10_scatter1d | ||
else: | ||
name = plotItem.labels[-1] if isinstance(plotItem.labels, list) else '' | ||
return subPlot.plot.plot(x.flatten(), 20*np.log10(y.flatten()), name=name, | ||
pen=None, symbol=symbol, symbolBrush=color, | ||
symbolPen=None, symbolSize=symbolSize) | ||
|
||
def _colorPlot(self, plotItem: PlotItem) -> None: | ||
subPlot = self.subPlotFromId(plotItem.subPlot) | ||
|
@@ -226,6 +244,7 @@ def _colorPlot(self, plotItem: PlotItem) -> None: | |
def _scatterPlot2d(self, plotItem: PlotItem) -> None: | ||
subPlot = self.subPlotFromId(plotItem.subPlot) | ||
assert isinstance(subPlot, PlotWithColorbar) and len(plotItem.data) == 3 | ||
assert not self.complexRepresentation == ComplexRepresentation.log_MagAndPhase | ||
subPlot.setScatter2d(*plotItem.data) | ||
|
||
|
||
|
@@ -312,6 +331,22 @@ def _plotData(self, **kwargs: Any) -> None: | |
self.fmWidget.setTitle(self.data.meta_val('title')) | ||
self.title = self.data.meta_val('title') | ||
|
||
#update FigOptions numAxes and imagData | ||
self.figOptions.numAxes = len(inds) | ||
for val in dvals: | ||
if isinstance(val, np.complex128): | ||
if not val.imag == 0: | ||
self.figOptions.imagData = True | ||
break | ||
if not all(val.imag == 0): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This line is currently crashing on my machine |
||
self.figOptions.imagData = True | ||
break | ||
#Assertions to make mypy happy | ||
assert self.figConfig is not None | ||
assert self.figConfig.updateComplexButton() is not None | ||
|
||
self.figConfig.updateComplexButton() | ||
|
||
@Slot() | ||
def _refreshPlot(self) -> None: | ||
self._plotData() | ||
|
@@ -346,7 +381,7 @@ def onfigSaved(self) -> None: | |
screenshot.save(str(path.parent)+'/'+filename, format='PNG') | ||
return | ||
|
||
logger.error("Could not find the path of the figuer. Figure has not been saved") | ||
logger.error("Could not find the path of the figure. Figure has not been saved") | ||
|
||
# TODO: Allow for the option to choose filetypes and the name/directory | ||
|
||
|
@@ -361,6 +396,10 @@ class FigureOptions: | |
#: how to represent complex data | ||
complexRepresentation: ComplexRepresentation = ComplexRepresentation.realAndImag | ||
|
||
numAxes: int = 0 | ||
|
||
imagData: bool = False | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should there be comments explaining what they are? they look pretty self explanatory but maybe? |
||
|
||
|
||
class FigureConfigToolBar(QtWidgets.QToolBar): | ||
"""Simple toolbar to configure the figure.""" | ||
|
@@ -394,11 +433,39 @@ def __init__(self, options: FigureOptions, | |
lambda: self._setOption('combineLinePlots', | ||
combineLinePlots.isChecked()) | ||
) | ||
complexOptions = QtWidgets.QMenu(parent=self) | ||
complexGroup = QtWidgets.QActionGroup(complexOptions) | ||
complexGroup.setExclusive(True) | ||
self._createComplexRepresentation() | ||
|
||
# Adding functionality to copy and save the graph | ||
self.copyFig = self.addAction('Copy Figure', self._copyFig) | ||
self.saveFig = self.addAction('Save Figure', self._saveFig) | ||
|
||
|
||
def _setOption(self, option: str, value: Any) -> None: | ||
setattr(self.options, option, value) | ||
self.optionsChanged.emit() | ||
|
||
def _copyFig(self) -> None: | ||
self.figCopied.emit() | ||
|
||
def _saveFig(self) -> None: | ||
self.figSaved.emit() | ||
|
||
def _createComplexRepresentation(self) -> bool: | ||
#constructs/reconstructs the Complex Button with different viewing options based upon input data | ||
|
||
complexOptions = QtWidgets.QMenu(parent=self) | ||
complexGroup = QtWidgets.QActionGroup(complexOptions) | ||
complexGroup.setExclusive(True) | ||
|
||
for k in ComplexRepresentation: | ||
|
||
#Checks instance of non-imaginary data (to only enable real view) and 2 independent variables (to disable logMag view) | ||
if not self.options.imagData and not k == ComplexRepresentation.real: continue | ||
if self.options.numAxes == 2 and k == ComplexRepresentation.log_MagAndPhase: continue | ||
|
||
a = QtWidgets.QAction(k.label, complexOptions) | ||
a.setCheckable(True) | ||
complexGroup.addAction(a) | ||
|
@@ -413,18 +480,16 @@ def __init__(self, options: FigureOptions, | |
complexButton.setText('Complex') | ||
complexButton.setPopupMode(QtWidgets.QToolButton.InstantPopup) | ||
complexButton.setMenu(complexOptions) | ||
self.addWidget(complexButton) | ||
|
||
# Adding functionality to copy and save the graph | ||
self.copyFig = self.addAction('Copy Figure', self._copyFig) | ||
self.saveFig = self.addAction('Save Figure', self._saveFig) | ||
|
||
def _setOption(self, option: str, value: Any) -> None: | ||
setattr(self.options, option, value) | ||
self.optionsChanged.emit() | ||
|
||
def _copyFig(self) -> None: | ||
self.figCopied.emit() | ||
|
||
def _saveFig(self) -> None: | ||
self.figSaved.emit() | ||
#stylistic edit to ensure that complexButton is the second button, also to ensure that the updateComplexButton removes the correct button | ||
if len(self.actions()) == 1: | ||
self.addWidget(complexButton) | ||
else: | ||
self.insertAction(self.actions()[1],self.addWidget(complexButton)) | ||
return True | ||
|
||
def updateComplexButton(self) -> bool: | ||
#remove the second action in the list (currently corresponding to the complexRepresentation button) | ||
self.removeAction(self.actions()[1]) | ||
self._createComplexRepresentation() | ||
return True |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
convert these 2 lines into 4. There is no need to save on vertical space