Skip to content

Commit

Permalink
Fix symbol scaling issues/add symbol command
Browse files Browse the repository at this point in the history
It bugged the **** out of me that symbol scaling didn't work (e.g. "ptsz 8"
didn't do nothing for the data points). After carefully reading PGPLOT
documentation and inspection of the plot commands:
    the code used symbol "-2" for plotting data points.

According to docs https://sites.astro.caltech.edu/~tjp/pgplot/subroutines.html#PGPT
this symbol scales with *linewidth* in stead of character height.

After testing turned out that PGPLOT 5.2.2 (on our Linux 18.04 server) still
doesn't honour this. Nor does Giza for that matter (tested).

Solution: support setting symbol numbers for the different data categories:
Unflagged, Flagged, Marked, Markedflagged. This allows user to set a
scaling symbol (e.g. #17) for the data points, which does honour "ptsz"
setting. Introduced "symbol" command for this.

Found that markers were drawn not honouring "marksz" setting:code set
different line width in stead of character height. (fixed)
  • Loading branch information
haavee authored and Marjolein Verkouter committed Jul 27, 2022
1 parent f884650 commit 09ca8e4
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 29 deletions.
7 changes: 7 additions & 0 deletions hvutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -444,3 +444,10 @@ def mo_or_org(x, **convdict):
def split_optarg(*args, **convdict):
(a, o) = partition(lambda x: isinstance(x, str), map(lambda y: mo_or_org(y, **convdict), args))
return (a, dict(o))


# Simple+slow uniq/unique function that retains order
# cf. https://stackoverflow.com/a/37163210
def uniq(l):
used = set()
return [x for x in l if x not in used and (used.add(x) or True)]
1 change: 1 addition & 0 deletions jenums.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@
Axes = enumerations.Enum('P', 'CH', 'SB', 'FQ', 'BL', 'SRC', 'TIME', 'TYPE')
Averaging = enumerations.Enum('NoAveraging', 'Scalar', 'Vector', 'Vectornorm', 'Sum', 'Vectorsum')
Flagstuff = enumerations.Enum('Unflagged', 'Flagged', 'Both')
Symbol = enumerations.Enum("Unflagged", "Flagged", "Marked", "Markedflagged")
46 changes: 42 additions & 4 deletions jplotter.py
Original file line number Diff line number Diff line change
Expand Up @@ -418,10 +418,11 @@ def pgqwin():
ppgplot.pgqwin = pgqwin


CP = copy.deepcopy
NOW = time.time
AVG = jenums.Averaging
FLAG = jenums.Flagstuff
CP = copy.deepcopy
NOW = time.time
AVG = jenums.Averaging
FLAG = jenums.Flagstuff
SYMBOL = jenums.Symbol

pwidth = lambda p, w: "{0:{1}}".format(p, w)
ppfx = lambda p: pwidth(p, 10)
Expand Down Expand Up @@ -1382,6 +1383,36 @@ def proc_arg(acc, arg):
if hl:
print("{0} {1}".format(pplt("show[{0}]:".format(curPlotType)), " ".join(hl)))


## Display or set symbols for the different data types (unflagged, flagged, marked, marked+flagged)
def symbolSetting(self, *args):
curPlotType = self.getPlotType()
curPlot = None if curPlotType is None else plots.Plotters[curPlotType]
if curPlot is None:
raise RuntimeError("No plot type selected to operate on")

args = filter_(operator.truth, args)
toshow = list() if args else [SYMBOL.Unflagged, SYMBOL.Flagged, SYMBOL.Marked, SYMBOL.Markedflagged]
isArg = re.compile(r'^(?P<which>[^=]+)(=(?P<what>[0-9]+))?$').match

def proc_arg(acc, arg):
mo = isArg(arg)
if not mo:
raise SyntaxError("The argument '{0}' does not look like <name> or <name>=<number>".format(arg))
which = mo.group( 'which' ).capitalize()
if which not in SYMBOL:
raise RuntimeError("Data type '{0}' is unrecognized".format(which))
what = mo.group('what')
if what:
curPlot.setSymbol(which, int(what))
toshow.append( which )

reduce(proc_arg, args, curPlot)
# now collect the values for all the selected types
cur = map(lambda w: "{0}={1}".format(w, curPlot.setSymbol(w)), hvutil.uniq(toshow))
print("{0} {1}".format(pplt("symbol[{0}]:".format(curPlotType)), "\t".join(cur)))


## raw TaQL string manipulation ..
def taqlStr(self, *args):
if args:
Expand Down Expand Up @@ -2913,6 +2944,13 @@ def write_tab(tabname):
args=lambda x: re.sub("^postprocess\s*", "", x).split(),
cb=lambda *args: env().postProcess(*args)) )

# set/inspect symbols
c.addCommand( \
mkcmd(rx=re.compile(r"^symbol\b.*"), id="symbol",
hlp="symbol [type,type=N]\n\tDisplay/set symbol number (PGPLOT) for types of data",
args=lambda x: re.sub("^symbol\s*", "", x).split(),
cb=lambda *args: j().symbolSetting(*args)) )

def test_f(*args):
print("test_f/n_arg=", len(args), " args=", args)

Expand Down
65 changes: 40 additions & 25 deletions plots.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

AX = jenums.Axes
FLAG = jenums.Flagstuff
SYMBOL = jenums.Symbol
Scaling = enumerations.Enum("auto_global", "auto_local")
FixFlex = enumerations.Enum("fixed", "flexible")
RowsCols = enumerations.Enum("rows", "columns")
Expand Down Expand Up @@ -892,6 +893,14 @@ def __init__(self, desc, xaxis, yaxis, lo, xscaling=None, yscaling=None, yheight
self.defaultShowHeader = True
self.defaultShowLegend = True
self.defaultShowSource = True
# Drawing attributes
self.defaultPointSize = 1
self.defaultLineWidth = 2
self.defaultMarkerSize = 1.5
self.defaultCharSize = 0 # zero = auto-scale, otherwise use this value
# Symbols for the different categories
self.defaultSymbol = {SYMBOL.Unflagged: -2, SYMBOL.Flagged: 5,
SYMBOL.Marked: 7, SYMBOL.Markedflagged: 27 }

# dict mapping a specific drawer to a method call on self
self.drawfuncs = { Drawers.Points: lambda dev, x, y, tp: self.drawPoints(dev, x, y, tp),
Expand Down Expand Up @@ -937,10 +946,11 @@ def reset(self):
self.filter_fun = CP(self.defaultFilter)
self.filter_fun_s = CP(self.defaultFilterS)
self.multiSubband = False
self.lineWidth = 2
self.pointSize = 4
self.markerSize = 6
self.charSize = 0 # zero = auto-scale, otherwise use this value
self.lineWidth = CP(self.defaultLineWidth)
self.pointSize = CP(self.defaultPointSize)
self.markerSize = CP(self.defaultMarkerSize)
self.charSize = CP(self.defaultCharSize)
self.symbol = CP(self.defaultSymbol)
self.drawMethod = CP([""]*len(self.yAxis))
self.drawers = CP([[]]*len(self.yAxis))
self.setDrawer(*str(self.defaultDrawer).split())
Expand Down Expand Up @@ -1078,6 +1088,11 @@ def setCharSize(self, *args):
self.charSize = args[0]
return self.charSize

def setSymbol(self, sym, *args):
if args:
self.symbol[sym] = args[0]
return self.symbol[sym]

# some plot types (notably those <quantity> vs frequency/channel)
# may support plotting all subband *next* to each other in stead
# of on top of each other. Use "True" or "False"
Expand Down Expand Up @@ -1351,20 +1366,20 @@ def drawfunc(self, device, plotar, first, onePage=None, **opts):
(mu, mf) = (None, None)
# Any unflagged data to display?
if data.xval is not None:
drap(functional.ylppa(device, xform_x(data.xval), data.yval, -2), self.drawers[subplot])
drap(functional.ylppa(device, xform_x(data.xval), data.yval, self.symbol[SYMBOL.Unflagged]), self.drawers[subplot])
mu = self.markedPointsForYAxis(subplot, data.xval, data.yval)
# Any flagged data to display?
if data.xval_f is not None:
drap(functional.ylppa(device, xform_x(data.xval_f), data.yval_f, 5), self.drawers[subplot])
drap(functional.ylppa(device, xform_x(data.xval_f), data.yval_f, self.symbol[SYMBOL.Flagged]), self.drawers[subplot])
mf = self.markedPointsForYAxis(subplot, data.xval_f, data.yval_f)
# draw markers if necessary, temporarily changing line width(markersize)
lw = device.pgqlw()
device.pgslw(self.markerSize)
ch = device.pgqch()
device.pgsch(self.markerSize)
if mu:
device.pgpt( xform_x(data.xval[mu]), data.yval[mu], 7)
device.pgpt( xform_x(data.xval[mu]), data.yval[mu], self.symbol[SYMBOL.Marked])
if mf:
device.pgpt( xform_x(data.xval_f[mf]), data.yval_f[mf], 27)
device.pgslw(lw)
device.pgpt( xform_x(data.xval_f[mf]), data.yval_f[mf], self.symbol[SYMBOL.Markedflagged])
device.pgsch(ch)
# Any extra drawing commands?
self.doExtraCallbacks(device, data, xoffset=day0hr)
# do some extra work for panel (subplot) number 0
Expand Down Expand Up @@ -1461,20 +1476,20 @@ def drawfunc(self, device, plotar, first, onePage=None, **opts):
(mu, mf) = (None, None)
# Any unflagged data to display?
if data.xval is not None:
drap(functional.ylppa(device, xform_x(data.xval), data.yval, -2), self.drawers[0])
drap(functional.ylppa(device, xform_x(data.xval), data.yval, self.symbol[SYMBOL.Unflagged]), self.drawers[0])
mu = self.markedPointsForYAxis(0, data.xval, data.yval)
# Any flagged data to display?
if data.xval_f is not None:
drap(functional.ylppa(device, xform_x(data.xval_f), data.yval_f, 5), self.drawers[0])
drap(functional.ylppa(device, xform_x(data.xval_f), data.yval_f, self.symbol[SYMBOL.Flagged]), self.drawers[0])
mf = self.markedPointsForYAxis(0, data.xval_f, data.yval_f)
# draw markers if necessary, temporarily changing line width(markersize)
lw = device.pgqlw()
device.pgslw(self.markerSize)
ch = device.pgqch()
device.pgsch(self.markerSize)
if mu:
device.pgpt( xform_x(data.xval[mu]), data.yval[mu], 7)
device.pgpt( xform_x(data.xval[mu]), data.yval[mu], self.symbol[SYMBOL.Marked])
if mf:
device.pgpt( xform_x(data.xval_f[mf]), data.yval_f[mf], 27)
device.pgslw(lw)
device.pgpt( xform_x(data.xval_f[mf]), data.yval_f[mf], self.symbol[SYMBOL.Markedflagged])
device.pgsch(ch)
# Any extra drawing commands?
self.doExtraCallbacks(device, data)
# and draw the main plot label
Expand Down Expand Up @@ -1591,20 +1606,20 @@ def drawfunc(self, device, plotar, first, onePage=None, **opts):
(mu, mf) = (None, None)
# Any unflagged data to display?
if data.xval is not None:
drap(functional.ylppa(device, xform_x(data.xval), data.yval, -2), self.drawers[subplot])
drap(functional.ylppa(device, xform_x(data.xval), data.yval, self.symbol[SYMBOL.Unflagged]), self.drawers[subplot])
mu = self.markedPointsForYAxis(subplot, data.xval, data.yval)
# Any flagged data to display?
if data.xval_f is not None:
drap(functional.ylppa(device, xform_x(data.xval_f), data.yval_f, 5), self.drawers[subplot])
drap(functional.ylppa(device, xform_x(data.xval_f), data.yval_f, self.symbol[SYMBOL.Flagged]), self.drawers[subplot])
mf = self.markedPointsForYAxis(subplot, data.xval_f, data.yval_f)
# draw markers if necessary, temporarily changing line width(markersize)
lw = device.pgqlw()
device.pgslw(self.markerSize)
ch = device.pgqch()
device.pgsch(self.markerSize)
if mu:
device.pgpt( xform_x(data.xval[mu]), data.yval[mu], 7)
device.pgpt( xform_x(data.xval[mu]), data.yval[mu], self.symbol[SYMBOL.Marked])
if mf:
device.pgpt( xform_x(data.xval_f[mf]), data.yval_f[mf], 27)
device.pgslw(lw)
device.pgpt( xform_x(data.xval_f[mf]), data.yval_f[mf], self.symbol[SYMBOL.Markedflagged])
device.pgsch(ch)
# Any extra drawing commands?
self.doExtraCallbacks(device, data)
# do some extra work for panel (subplot) number 0
Expand Down

0 comments on commit 09ca8e4

Please sign in to comment.