Skip to content
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

Merged
merged 20 commits into from
Jun 14, 2023
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
fc27f24
Added Log(mag**2)
jeremiahnlin May 24, 2023
a1c566a
Merge branch 'log_scale' of https://github.com/jeremiahnlin/plottr in…
jeremiahnlin May 24, 2023
3767bb0
changed label of logmag
jeremiahnlin May 24, 2023
af3a0cf
added log lines to new complexRepresentation
jeremiahnlin May 25, 2023
0091ebb
made so the complexRepresentation did not have log scale for phase, m…
jeremiahnlin May 25, 2023
e50f25c
changed complexRepresentation to 20*log10(mag) and took out logarithm…
jeremiahnlin May 26, 2023
738a4fd
Merge branch 'toolsforexperiments:master' into log_scale
jeremiahnlin May 26, 2023
f4c81e7
made style revisions
jeremiahnlin May 26, 2023
6a7c1b0
more style edits
jeremiahnlin May 26, 2023
98a7b31
Merge branch 'toolsforexperiments:master' into log_scale
jeremiahnlin May 31, 2023
d28f399
disabled logmag for two independent axes
jeremiahnlin Jun 7, 2023
e8ce42b
changed so non-imaginary data will only have the option for real comp…
jeremiahnlin Jun 7, 2023
d523cee
Merge branch 'toolsforexperiments:master' into log_scale
jeremiahnlin Jun 7, 2023
f8260f0
stylistic changes
jeremiahnlin Jun 7, 2023
875fc75
mypy check fix maybe?
jeremiahnlin Jun 7, 2023
9fa3772
maybe fixed the mypy issues
jeremiahnlin Jun 7, 2023
d4ad24b
style changes and fixed crashing error
jeremiahnlin Jun 9, 2023
a5638bc
fixed minor naming issue
jeremiahnlin Jun 9, 2023
41dad4d
helped readability with _1dPlot function
jeremiahnlin Jun 9, 2023
d5c1ed2
changed readability of _1dPlot
jeremiahnlin Jun 9, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 42 additions & 2 deletions plottr/plot/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,12 @@ class PlotDataType(Enum):
#: grid data with 2 dependents
grid2d = auto()

#: logarithmic scatter-type data with 1 dependent (data is not on a grid)
log10_scatter1d = auto()

#: logarithmic line data with 1 dependent (data is on a grid)
log10_line1d = auto()


class ComplexRepresentation(LabeledOptions):
"""Options for plotting complex-valued data."""
Expand All @@ -264,6 +270,11 @@ class ComplexRepresentation(LabeledOptions):
#: magnitude and phase
magAndPhase = "Mag/Phase"

#: Natural Logarithmic magnitude and phase
log10_MagAndPhase = "20*log10(Mag)/Phase"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would just rename it to logMag/Phase or something like that. Like this seems to long for me





def determinePlotDataType(data: Optional[DataDictBase]) -> PlotDataType:
"""
Expand Down Expand Up @@ -422,7 +433,7 @@ def _splitComplexData(self, plotItem: PlotItem) -> List[PlotItem]:

if not np.issubsctype(plotItem.data[-1], np.complexfloating):
return [plotItem]

elif self.complexRepresentation is ComplexRepresentation.real:
plotItem.data[-1] = plotItem.data[-1].real
assert isinstance(plotItem.labels, list)
Expand All @@ -431,7 +442,7 @@ def _splitComplexData(self, plotItem: PlotItem) -> List[PlotItem]:
else:
plotItem.labels[-1] = label + ' (Real)'
return [plotItem]

elif self.complexRepresentation in \
[ComplexRepresentation.realAndImag, ComplexRepresentation.realAndImagSeparate]:

Expand Down Expand Up @@ -463,6 +474,35 @@ def _splitComplexData(self, plotItem: PlotItem) -> List[PlotItem]:

return [re_plotItem, im_plotItem]

elif self.complexRepresentation == ComplexRepresentation.log10_MagAndPhase:
data = plotItem.data[-1]

# this check avoids a numpy ComplexWarning when we're working with MaskedArray (almost always)
mag_data = np.ma.abs(data).real if isinstance(data, np.ma.MaskedArray) else np.abs(data)
phase_data = np.angle(data)

if label == '':
mag_label, phase_label = '20*log10(Mag)', 'Phase'
else:
mag_label, phase_label = label + ' 20*log10(Mag)', label + ' (Phase)'

mag_plotItem = plotItem
phase_plotItem = deepcopy(mag_plotItem)

mag_plotItem.data[-1] = mag_data
phase_plotItem.data[-1] = phase_data
phase_plotItem.id = mag_plotItem.id + 1
phase_plotItem.subPlot = mag_plotItem.subPlot + 1

# this is a bit of a silly check (see top of the function -- should certainly be True!).
# but it keeps mypy happy.
assert isinstance(mag_plotItem.labels, list)
mag_plotItem.labels[-1] = mag_label
assert isinstance(phase_plotItem.labels, list)
phase_plotItem.labels[-1] = phase_label

return [mag_plotItem, phase_plotItem]

else: # means that self.complexRepresentation is ComplexRepresentation.magAndPhase:
data = plotItem.data[-1]

Expand Down
25 changes: 22 additions & 3 deletions plottr/plot/pyqtgraph/autoplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,13 +179,21 @@ def formatSubPlot(self, subPlotId: int) -> None:

def plot(self, plotItem: PlotItem) -> None:
"""Plot the given item."""

if plotItem.plotDataType is PlotDataType.unknown:
if len(plotItem.data) == 2:
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 for 20*log10(Mag) and it's regarding the Magnitude Plot, not the Phase Plot
if self.complexRepresentation == ComplexRepresentation.log10_MagAndPhase and plotItem.subPlot == 0:

#Switch the 1d plots to the logarithmic variation
if plotItem.plotDataType == PlotDataType.scatter1d: plotItem.plotDataType = PlotDataType.log10_scatter1d
if plotItem.plotDataType == PlotDataType.line1d: 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)
Expand All @@ -212,11 +220,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 ''
Copy link
Collaborator

Choose a reason for hiding this comment

The 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)
Expand Down