@@ -18,7 +18,7 @@ def hapiplot(*args, **kwargs):
1818 """Plot response from HAPI server.
1919
2020 Version: 0.2.3b0
21-
21+
2222 Demos
2323 -----
2424 <https://github.com/hapi-server/client-python/blob/master/hapiclient/plot/hapiplot_test.py>
@@ -170,12 +170,12 @@ def hapiplot(*args, **kwargs):
170170 opts = setopts (opts , kwargs )
171171
172172 from hapiclient import __version__
173- log ('Running hapi.py version %s' % __version__ , opts )
173+ log ('Using hapi.py version %s' % __version__ , opts )
174174
175175 from hapiplot import __version__
176176 from matplotlib import __version__ as mpl_version
177-
178- log ('Running hapiplot.py version %s with Matplotlib version %s' % \
177+
178+ log ('hapiplot version %s using Matplotlib version %s' % \
179179 (__version__ , mpl_version ), opts )
180180
181181 # _rcParams are not actually rcParams:
@@ -194,33 +194,25 @@ def hapiplot(*args, **kwargs):
194194 nodata = False
195195 if len (data [timename ]) == 0 :
196196 nodata = True
197+ # Set time to request range to set x-axis
197198 Time = hapitime2datetime (np .array ([meta ['x_time.min' ], meta ['x_time.max' ]]), allow_missing_Z = True )
198- data = np .ndarray (shape = (2 ,), dtype = data .dtype )
199- #data[timename] = Time
200199 else :
201200 Time = hapitime2datetime (data [timename ], allow_missing_Z = True )
202201
203202 if len (meta ["parameters" ]) == 1 :
204203 a = 0 # Time is only parameter
205204 else :
206- a = 1 # Time plus another parameter
205+ a = 1 # Time plus one or more parameters
207206
208207 for i in range (a , len (meta ["parameters" ])):
209208
210209 meta ["parameters" ][i ]['hapiplot' ] = {}
211210
212- name = meta ["parameters" ][i ]["name" ]
213-
214- if nodata :
215- # Use NaN values for plot
216- data [name ] = np .full (data .dtype [i ].shape , np .nan )
217-
218-
219211 name = meta ["parameters" ][i ]["name" ]
220212
221213 if len (data [name ].shape ) > 3 :
222214 # TODO: Implement more than 2 dimensions?
223- warning ( ' Parameter ' + name + ' has size with more than 2 dimensions. Plotting first two only.' )
215+ log ( " Parameter '%s ' has more than two components. Skipping." % name , opts )
224216 continue
225217
226218 # If parameter has a size with two elements, e.g., [N1, N2]
@@ -229,23 +221,22 @@ def hapiplot(*args, **kwargs):
229221
230222 log ("Parameter '%s' has 3 components. Creating one plot per component." % name , opts )
231223
232- pidx = 1 # Primary index is N2
224+ pidx = 1 # Primary (fastest varying) index is N2
233225 sidx = 0 # Secondary index is N1
234226 nplts = data [name ].shape [1 ]
235227 if data [name ].shape [1 ] > data [name ].shape [2 ]:
236228 pidx = 0
237229 sidx = 1
238230 nplts = data [name ].shape [2 ]
239231
240-
241232 if opts ['returnimage' ]:
242233 warning ('Only returning first image for parameter with size[1] > 1.' )
243234 nplts = 1
235+
244236 for j in range (nplts ):
245237 timename = meta ['parameters' ][0 ]['name' ]
246238
247239 # Name to indicate what is plotted
248-
249240 if pidx > sidx :
250241 name_new = name + "[" + str (j ) + ",:]"
251242 else :
@@ -318,7 +309,8 @@ def hapiplot(*args, **kwargs):
318309 opts ['rcParams' ] = kwargs ['rcParams' ]
319310
320311 metar = hapiplot (datar , metar , ** opts )
321- meta ["parameters" ][i ]['hapiplot' ] = metar ["parameters" ][i ]['hapiplot' ]
312+
313+ meta ["parameters" ][i ]['hapiplot' ] = metar ["parameters" ][1 ]['hapiplot' ]
322314 return meta
323315
324316 # Return cached image (case where we are returning binary image data)
@@ -362,6 +354,7 @@ def hapiplot(*args, **kwargs):
362354
363355 if 'units' in meta ["parameters" ][i ] and type (meta ["parameters" ][i ]["units" ]) == list :
364356 if as_heatmap :
357+ # TODO: Verify that all units not the same
365358 warning ("Not plotting %s as heatmap because components have different units." % meta ["parameters" ][i ]["name" ])
366359 as_heatmap = False
367360
@@ -377,18 +370,23 @@ def hapiplot(*args, **kwargs):
377370 warning ("Plots for only types double, integer, and isotime implemented. Not plotting %s." % meta ["parameters" ][i ]["name" ])
378371 continue
379372
380- z = np .asarray (data [name ])
373+ if nodata :
374+ if a == 0 :
375+ # Time is only parameter
376+ z = np .full ((2 ,), np .nan )
377+ else :
378+ if 'size' in meta ['parameters' ][i ]:
379+ z = np .full ((2 , meta ['parameters' ][i ]['size' ][0 ]), np .nan )
380+ else :
381+ z = np .full ((2 ,), np .nan )
382+ else :
383+ z = np .asarray (data [name ])
381384
382385 if 'fill' in meta ["parameters" ][i ] and meta ["parameters" ][i ]['fill' ]:
383386 if meta ["parameters" ][i ]["type" ] == 'integer' :
384387 z = z .astype ('<f8' , copy = False )
385388 z = fill2nan (z , meta ["parameters" ][i ]['fill' ])
386389
387- if 'bins' in meta ['parameters' ][i ]:
388- ylabel = meta ["parameters" ][i ]['bins' ][0 ]["name" ] + " [" + meta ["parameters" ][i ]['bins' ][0 ]["units" ] + "]"
389- else :
390- ylabel = "col %d" % i
391-
392390 units = meta ["parameters" ][i ]["units" ]
393391 nl = ""
394392 if len (name ) + len (units ) > 30 :
@@ -399,31 +397,51 @@ def hapiplot(*args, **kwargs):
399397 if units is not None :
400398 zlabel = " [" + units + "]"
401399
400+ bins = np .arange (meta ['parameters' ][i ]['size' ][0 ])
401+ bins_time_dependent = False
402402 if 'bins' in meta ['parameters' ][i ]:
403403 if 'ranges' in meta ["parameters" ][i ]['bins' ][0 ]:
404- bins = np .array (meta ["parameters" ][i ]['bins' ][0 ]["ranges" ])
404+ if isinstance (meta ['parameters' ][i ]['bins' ][0 ]['ranges' ], str ) is False :
405+ bins = np .array (meta ["parameters" ][i ]['bins' ][0 ]["ranges" ])
406+ else :
407+ bins_time_dependent = True
405408 else :
406- bins = np .array (meta ["parameters" ][i ]['bins' ][0 ]["centers" ])
409+ if isinstance (meta ['parameters' ][i ]['bins' ][0 ]['centers' ], str ) is False :
410+ bins = np .array (meta ["parameters" ][i ]['bins' ][0 ]["centers" ])
411+ else :
412+ bins_time_dependent = True
413+
414+ if 'bins' in meta ['parameters' ][i ] and not bins_time_dependent :
415+ ylabel = meta ["parameters" ][i ]['bins' ][0 ]["name" ] \
416+ + " [" \
417+ + meta ["parameters" ][i ]['bins' ][0 ]["units" ] \
418+ + "]"
407419 else :
408- bins = np .arange (meta ['parameters' ][i ]['size' ][0 ])
420+ ylabel = "bin #"
421+ if bins_time_dependent :
422+ ylabel = "bin #\n (vals are time dependent)"
409423
410424 dt = np .diff (Time )
411425 dtu = np .unique (dt )
412426 if len (dtu ) > 1 :
413- # warning('Time values are not uniformly spaced. Bin width for '
414- # 'time will be based on time separation of consecutive time values.')
427+ warning ('Time values are not uniformly spaced. Bin width for '
428+ 'time will be based on time separation of consecutive time values.' )
415429 # Cadence != time bin width in general, so can't use cadence.
416430 # See https://github.com/hapi-server/data-specification/issues/75
417431 if 'timeStampLocation' in meta and meta ['timeStampLocation' ].lower () == "begin" :
432+ deltat = dt [0 ]
418433 for t in range (0 ,Time .size ):
419- Time [t ] = Time [t ] + dt [i ]
434+ Time [t ] = Time [t ] + dt [t ]
420435 elif 'timeStampLocation' in meta and meta ['timeStampLocation' ].lower () == "end" :
421436 for t in range (0 ,Time .size ):
437+ deltat = - dt [0 ]
422438 Time [t ] = Time [t ] - dt [i ]
423439 else :
424- for t in range (0 ,Time .size ):
425- Time [t ] = Time [t ] - dt [i ]/ 2
440+ deltat = - dt [0 ]/ 2
426441
442+ for t in range (0 ,Time .size ):
443+ Time [t ] = Time [t ] + deltat
444+
427445 Time = np .append (Time , Time [- 1 ] + dt [- 1 ])
428446
429447 elif 'timeStampLocation' in meta :
@@ -463,7 +481,6 @@ def hapiplot(*args, **kwargs):
463481 if opts ['logz' ] is not False :
464482 hmopts ['logz' ] = True
465483
466-
467484 for key , value in opts ['hmopts' ].items ():
468485 hmopts [key ] = value
469486
@@ -482,18 +499,26 @@ def hapiplot(*args, **kwargs):
482499 'backend' : opts ['backend' ]
483500 }
484501
485-
486502 ptype = meta ["parameters" ][i ]["type" ]
487- if ptype == "isotime" :
488- y = hapitime2datetime (data [name ],allow_missing_Z = True )
489- elif ptype == 'string' :
490- y = data [name ].astype ('U' )
503+ if nodata :
504+ if a == 0 :
505+ # Time is only parameter
506+ y = np .full ((2 ,), np .nan )
507+ else :
508+ if 'size' in meta ['parameters' ][i ]:
509+ y = np .full ((2 ,meta ['parameters' ][i ]['size' ][0 ]), np .nan )
510+ else :
511+ y = np .full ((2 ,), np .nan )
491512 else :
492- y = np .asarray (data [name ])
493-
513+ if ptype == "isotime" :
514+ y = hapitime2datetime (data [name ],allow_missing_Z = True )
515+ elif ptype == 'string' :
516+ y = data [name ].astype ('U' )
517+ else :
518+ y = np .asarray (data [name ])
494519
495520 if 'fill' in meta ["parameters" ][i ] and meta ["parameters" ][i ]['fill' ]:
496- if ptype == 'isotime' or ptype == 'string' :
521+ if nodata == False and ptype == 'isotime' or ptype == 'string' :
497522 Igood = y != meta ["parameters" ][i ]['fill' ]
498523 # Note that json reader returns fill to U not b.
499524 Nremoved = data [name ].size - Igood .size
@@ -510,6 +535,11 @@ def hapiplot(*args, **kwargs):
510535 if ptype == 'integer' or ptype == 'double' :
511536 y = fill2nan (y , meta ["parameters" ][i ]['fill' ])
512537
538+ remove_mean = False
539+ if 'uk/GIN_' in meta ['x_server' ]:
540+ remove_mean = True
541+ y_mean = np .nanmean (y , axis = 0 )
542+
513543 units = None
514544 if 'units' in meta ["parameters" ][i ] and meta ["parameters" ][i ]['units' ]:
515545 units = meta ["parameters" ][i ]["units" ]
@@ -562,7 +592,7 @@ def hapiplot(*args, **kwargs):
562592 bin_units = ' [' + bin_units + ']'
563593 else :
564594 bin_units = ' '
565-
595+
566596 if 'centers' in meta ['parameters' ][i ]['bins' ][0 ]:
567597 if meta ['parameters' ][i ]['bins' ][0 ]['centers' ][l ] is not None :
568598 bin_label = bin_label + ' center = ' + str (meta ['parameters' ][i ]['bins' ][0 ]['centers' ][l ]) + bin_units
@@ -573,7 +603,7 @@ def hapiplot(*args, **kwargs):
573603 if type (meta ['parameters' ][i ]['bins' ][0 ]['ranges' ][l ]) == list :
574604 if meta ['parameters' ][i ]['bins' ][0 ]['ranges' ][l ][0 ] and meta ['parameters' ][i ]['bins' ][0 ]['ranges' ][l ][1 ] is not None :
575605 bin_label = bin_label + sep + ' range = [' + str (meta ['parameters' ][i ]['bins' ][0 ]['ranges' ][l ][0 ]) + ', ' + str (meta ['parameters' ][i ]['bins' ][0 ]['ranges' ][l ][1 ]) + ']' + bin_units
576- #else:
606+ #else:
577607 # bin_label = bin_label + sep + ' range = [None]'
578608
579609 if bin_label != '' :
@@ -586,13 +616,26 @@ def hapiplot(*args, **kwargs):
586616 if nodata :
587617 col_name = col_name + " [no data in interval]"
588618
619+ if remove_mean :
620+ if y_mean [l ] > 0 :
621+ col_name = "{0:s} - {1:.2f}" .format (col_name , y_mean [l ])
622+ if y_mean [l ] < 0 :
623+ col_name = "{0:s} + {1:.2f}" .format (col_name , - y_mean [l ])
624+
589625 if 'label' in meta ['parameters' ][i ] and \
590626 type (meta ['parameters' ][i ]['label' ]) == list and \
591627 len (meta ['parameters' ][i ]['label' ]) > l and \
592628 meta ['parameters' ][i ]['label' ][l ].strip () != '' :
593629 col_name = meta ['parameters' ][i ]['label' ][l ]
594630 if nodata :
595631 col_name = col_name + " [no data in interval]"
632+ else :
633+ if remove_mean :
634+ if y_mean [l ] > 0 :
635+ col_name = "{0:s} - {1:.2f}" .format (col_name , y_mean [l ])
636+ if y_mean [l ] < 0 :
637+ col_name = "{0:s} + {1:.2f}" .format (col_name , - y_mean [l ])
638+
596639
597640 if type (units ) == list :
598641 if len (units ) == 1 :
@@ -633,8 +676,12 @@ def hapiplot(*args, **kwargs):
633676 if nodata == True :
634677 tsopts ['nodata' ] = True
635678
636- with rc_context (rc = opts ['rcParams' ]):
637- fig = timeseries (Time , y , ** tsopts )
679+ if remove_mean :
680+ with rc_context (rc = opts ['rcParams' ]):
681+ fig = timeseries (Time , y - y_mean , ** tsopts )
682+ else :
683+ with rc_context (rc = opts ['rcParams' ]):
684+ fig = timeseries (Time , y , ** tsopts )
638685
639686 meta ["parameters" ][i ]['hapiplot' ]['figure' ] = fig
640687
0 commit comments