def test_basic(self): for version in gmtpy.all_installed_gmt_versions(): width = 8.0 * inch height = 9.0 * inch resolution = 72 gmt = gmtpy.GMT(version=version, config_papersize=(width, height)) gmt.pscoast(X=0, Y=0, R='g', J='E32/30/170/8i', B='10g10', D='c', A=10000, S=(114, 159, 207), G=(233, 185, 110), W='thinnest') gmt.dump('test') gmt.load('test') for oversample in (1, 2): fname = 'gmtpy_test_basic_o%i.png' % oversample fpath = self.fpath(fname) gmt.save(fpath, resolution=resolution, oversample=oversample) self.compare_with_ref(fname, 0.02) img = image.imread(fpath, format='png') self.assertEqual(img.shape, (int(round(resolution * height / inch)), int(round(resolution * width / inch)), 3))
def test_basic2(self): for version in gmtpy.all_installed_gmt_versions(): if version.startswith('5'): gmt = gmtpy.GMT(version=version, config={'MAP_FRAME_TYPE': 'fancy'}, eps_mode=True) else: gmt = gmtpy.GMT(version=version, config={'BASEMAP_TYPE': 'fancy'}) layout = gmt.default_layout() widget = layout.get_widget() xax = gmtpy.Ax(label='Lon', mode='min-max') yax = gmtpy.Ax(label='Lat', mode='min-max') scaler = gmtpy.ScaleGuru([([5, 15], [52, 58])], axes=(xax, yax)) par = scaler.get_params() lon0 = (par['xmin'] + par['xmax']) / 2. lat0 = (par['ymin'] + par['ymax']) / 2. sll = '%g/%g' % (lon0, lat0) widget['J'] = '-JM' + sll + '/%(width)gp' widget['J'] = '-JM' + sll + '/%(width)gp' scaler['B'] = \ '-B%(xinc)gg%(xinc)g:%(xlabel)s:' \ '/%(yinc)gg%(yinc)g:%(ylabel)s:WSen' aspect = gmtpy.aspect_for_projection(version, *(widget.J() + scaler.R())) aspect = 1.045 widget.set_aspect(aspect) gmt.pscoast(D='h', W='1p,red', *(widget.JXY() + scaler.R())) gmt.psbasemap(*(widget.JXY() + scaler.BR())) fname = 'gmtpy_test_basic2.png' fpath = self.fpath(fname) gmt.save(fpath, resolution=75, bbox=layout.bbox()) self.compare_with_ref(fname, 0.01, show=False)
def _setup_gmt(self): w, h = self.width, self.height scaler = self._scaler gmtconf = dict( TICK_PEN='1.25p', TICK_LENGTH='0.2c', ANNOT_FONT_PRIMARY='1', ANNOT_FONT_SIZE_PRIMARY='12p', LABEL_FONT='1', LABEL_FONT_SIZE='12p', CHAR_ENCODING='ISOLatin1+', BASEMAP_TYPE='fancy', PLOT_DEGREE_FORMAT='D', PAPER_MEDIA='Custom_%ix%i' % ( w*gmtpy.cm, h*gmtpy.cm), GRID_PEN_PRIMARY='thinnest/0/50/0', DOTS_PR_INCH='1200', OBLIQUE_ANNOTATION='6') gmtconf.update( (k.upper(), v) for (k, v) in self.gmt_config.iteritems()) gmt = gmtpy.GMT(config=gmtconf) layout = gmt.default_layout() layout.set_fixed_margins(*[x*cm for x in self._expand_margins()]) widget = layout.get_widget() # widget['J'] = ('-JT%g/%g' % (self.lon, self.lat)) + '/%(width)gp' # widget['J'] = ('-JA%g/%g' % (self.lon, self.lat)) + '/%(width)gp' widget['P'] = widget['J'] widget['J'] = ('-JA%g/%g' % (self.lon, self.lat)) + '/%(width_m)gm' # widget['J'] = ('-JE%g/%g' % (self.lon, self.lat)) + '/%(width)gp' # scaler['R'] = '-R%(xmin)g/%(xmax)g/%(ymin)g/%(ymax)g' scaler['R'] = '-R%g/%g/%g/%gr' % self._corners aspect = gmtpy.aspect_for_projection(*(widget.J() + scaler.R())) widget.set_aspect(aspect) self._gmt = gmt self._layout = layout self._widget = widget self._jxyr = self._widget.JXY() + self._scaler.R() self._pxyr = self._widget.PXY() + [ '-R%g/%g/%g/%g' % (0, widget.width(), 0, widget.height())] self._have_drawn_axes = False self._have_drawn_labels = False
def _setup_gmt(self): w, h = self.width, self.height scaler = self._scaler gmtconf = dict( TICK_PEN="1.25p", TICK_LENGTH="0.2c", ANNOT_FONT_PRIMARY="1", ANNOT_FONT_SIZE_PRIMARY="12p", LABEL_FONT="1", LABEL_FONT_SIZE="12p", CHAR_ENCODING="ISOLatin1+", BASEMAP_TYPE="fancy", PLOT_DEGREE_FORMAT="D", PAPER_MEDIA="Custom_%ix%i" % (w * gmtpy.cm, h * gmtpy.cm), GRID_PEN_PRIMARY="thinnest/0/50/0", DOTS_PR_INCH="1200", OBLIQUE_ANNOTATION="6", ) gmtconf.update( (k.upper(), v) for (k, v) in self.gmt_config.iteritems()) gmt = gmtpy.GMT(config=gmtconf) layout = gmt.default_layout() layout.set_fixed_margins(*[x * cm for x in self._expand_margins()]) widget = layout.get_widget() widget["P"] = widget["J"] widget["J"] = ("-JE%g/%g" % (self.lon, self.lat)) + "/%(width)gp" scaler["R"] = "-R%g/%g/%g/%gr" % self._corners aspect = gmtpy.aspect_for_projection(*(widget.J() + scaler.R())) widget.set_aspect(aspect) self._gmt = gmt self._layout = layout self._widget = widget self._jxyr = self._widget.JXY() + self._scaler.R() self._pxyr = self._widget.PXY() + [ "-R%g/%g/%g/%g" % (0, widget.width(), 0, widget.height()) ] self._have_drawn_axes = False self._have_drawn_labels = False
def test_layout(self): x = num.linspace(0., math.pi * 6, 1001) y1 = num.sin(x) * 1e-9 y2 = 2.0 * num.cos(x) * 1e-9 xax = gmtpy.Ax(label='Time', unit='s') yax = gmtpy.Ax(label='Amplitude', unit='m', scaled_unit='nm', scaled_unit_factor=1e9, approx_ticks=5, space=0.05) guru = gmtpy.ScaleGuru([(x, y1), (x, y2)], axes=(xax, yax)) for version in gmtpy.all_installed_gmt_versions(): width = 8 * inch height = 3 * inch gmt = gmtpy.GMT(version=version, config_papersize=(width, height)) layout = gmt.default_layout() widget = layout.get_widget() gmt.draw_layout(layout) gmt.psbasemap(*(widget.JXY() + guru.RB(ax_projection=True))) gmt.psxy(in_columns=(x, y1), W='1p,red', *(widget.JXY() + guru.R())) gmt.psxy(in_columns=(x, y2), W='1p,blue', *(widget.JXY() + guru.R())) fname = 'gmtpy_test_layout.png' fpath = self.fpath(fname) gmt.save(fpath) self.compare_with_ref(fname, 0.01)
def test_override_args(self): x = num.array([0, 0.5, 1, 0]) y = num.array([0, 1, 0, 0]) width = 300 height = 100 config_papersize = (width, height) for version in gmtpy.all_installed_gmt_versions(): gmt = gmtpy.GMT(version=version, config_papersize=config_papersize) for i, cutoff in enumerate([30, 90]): gmt.psxy(in_columns=(i * 2 + x, y), W='10p,red', J='X%gp/%gp' % (width, height), X=0, Y=0, R=(-1, 4, -1, 2), config={'PS_MITER_LIMIT': '%i' % cutoff}) fname = 'gmtpy_test_override.png' fpath = self.fpath(fname) gmt.save(fpath) self.compare_with_ref(fname, 0.001, show=False)
def gmtplot_catalog_azimuthal(catalog, mid_point, dist, outfile, bin_width): """ Plot events of catalog on map :param catalog: event catalog in pyrocko format :param mid_point: centre of map :param dist: max. distance in degrees """ gmt = gmtpy.GMT( config={ 'MAP_GRID_PEN_PRIMARY': '0.1p', 'MAP_GRID_PEN_SECONDARY': '0.1p', #'MAP_GRID_PEN_TERTIARY': '0.001p', 'MAP_FRAME_TYPE': 'fancy', #'GRID_PEN_PRIMARY': '0.01p', #'GRID_PEN_SECONDARY': '0.01p', 'FONT_ANNOT_PRIMARY': '14p,Helvetica,black', 'FONT_ANNOT_SECONDARY': '14p,Helvetica,black', 'FONT_LABEL': '14p,Helvetica,black' }) gmt.psbasemap(R='0/360/-90/0', J='S0/-90/90/6i', B='xa%sf%s' % (bin_width * 2, bin_width)) gmt.pscoast(R='g', J='E%s/%s/%s/6i' % (mid_point[1], mid_point[0], dist), D='c', G='darkgrey') gmt.psbasemap(R='g', J='E0/-90/%s/6i' % dist, B='xg%s' % bin_width) gmt.psbasemap(R='g', J='E0/-90/%s/6i' % dist, B='yg%s' % bin_width) gmt.psxy(R='0/360/-90/0', J='E%s/%s/%s/6i' % (mid_point[1], mid_point[0], dist), in_columns=([ev.lon for ev in catalog], [ev.lat for ev in catalog]), G='red', S='a12p') gmt.save(outfile) logging.info('saved %s' % outfile)
def test_grid_layout(self): for version in gmtpy.all_installed_gmt_versions(): gmt = gmtpy.GMT(version=version, config_papersize='a3') nx, ny = 2, 5 grid = gmtpy.GridLayout(nx, ny) layout = gmt.default_layout() layout.set_widget('center', grid) widgets = [] for iy in range(ny): for ix in range(nx): inner = gmtpy.FrameLayout() inner.set_fixed_margins(1. * cm * golden_ratio, 1. * cm * golden_ratio, 1. * cm, 1. * cm) grid.set_widget(ix, iy, inner) inner.set_vertical(0, (iy + 1.)) widgets.append(inner.get_widget('center')) gmt.draw_layout(layout) for widget in widgets: x = num.linspace(0., 10., 5) y = num.sin(x) xax = gmtpy.Ax(approx_ticks=4, snap=True) yax = gmtpy.Ax(approx_ticks=4, snap=True) guru = gmtpy.ScaleGuru([(x, y)], axes=(xax, yax)) gmt.psbasemap(*(widget.JXY() + guru.RB(ax_projection=True))) gmt.psxy(in_columns=(x, y), *(widget.JXY() + guru.R())) fname = 'gmtpy_test_grid_layout.png' fpath = self.fpath(fname) gmt.save(fpath, resolution=75) self.compare_with_ref(fname, 0.01)
def _draw_labels(self): if self._labels: fontsize = self.gmt.to_points( self.gmt.gmt_config['LABEL_FONT_SIZE']) n = len(self._labels) lons, lats, texts, sx, sy, styles = zip(*self._labels) sx = num.array(sx, dtype=num.float) sy = num.array(sy, dtype=num.float) j, _, _, r = self.jxyr f = StringIO() self.gmt.mapproject(j, r, in_columns=(lons, lats), out_stream=f, D='p') f.seek(0) data = num.loadtxt(f, ndmin=2) xs, ys = data.T dxs = num.zeros(n) dys = num.zeros(n) g = gmtpy.GMT() g.psbasemap('-G0', finish=True, *(j, r)) l, b, r, t = g.bbox() h = (t - b) w = (r - l) for i in xrange(n): g = gmtpy.GMT() g.pstext(in_rows=[[0, 0, fontsize, 0, 1, 'BL', texts[i]]], finish=True, R=(0, 1, 0, 1), J='x10p', N=True, **styles[i]) fn = g.tempfilename() g.save(fn) (_, stderr) = Popen([ 'gs', '-q', '-dNOPAUSE', '-dBATCH', '-r720', '-sDEVICE=bbox', fn ], stderr=PIPE).communicate() dx, dy = None, None for line in stderr.splitlines(): if line.startswith('%%HiResBoundingBox:'): l, b, r, t = [float(x) for x in line.split()[-4:]] dx, dy = r - l, t - b dxs[i] = dx dys[i] = dy la = num.logical_and anchors_ok = ( la(xs + sx + dxs < w, ys + sy + dys < h), la(xs - sx - dxs > 0., ys - sy - dys > 0.), la(xs + sx + dxs < w, ys - sy - dys > 0.), la(xs - sx - dxs > 0., ys + sy + dys < h), ) arects = [(xs, ys, xs + sx + dxs, ys + sy + dys), (xs - sx - dxs, ys - sy - dys, xs, ys), (xs, ys - sy - dys, xs + sx + dxs, ys), (xs - sx - dxs, ys, xs, ys + sy + dys)] def no_points_in_rect(xs, ys, xmin, ymin, xmax, ymax): xx = not num.any( la(la(xmin < xs, xs < xmax), la(ymin < ys, ys < ymax))) return xx for i in xrange(n): for ianch in xrange(4): anchors_ok[ianch][i] &= no_points_in_rect( xs, ys, *[xxx[i] for xxx in arects[ianch]]) anchor_choices = [] anchor_take = [] for i in xrange(n): choices = [ ianch for ianch in xrange(4) if anchors_ok[ianch][i] ] anchor_choices.append(choices) if choices: anchor_take.append(choices[0]) else: anchor_take.append(None) def roverlaps(a, b): return (a[0] < b[2] and b[0] < a[2] and a[1] < b[3] and b[1] < a[3]) def cost(anchor_take): noverlaps = 0 for i in xrange(n): for j in xrange(n): if i != j: i_take = anchor_take[i] j_take = anchor_take[j] if i_take is None or j_take is None: continue r_i = [xxx[i] for xxx in arects[i_take]] r_j = [xxx[j] for xxx in arects[j_take]] if roverlaps(r_i, r_j): noverlaps += 1 return noverlaps cur_cost = cost(anchor_take) imax = 30 while cur_cost != 0 and imax > 0: for i in xrange(n): for t in anchor_choices[i]: anchor_take_new = list(anchor_take) anchor_take_new[i] = t new_cost = cost(anchor_take_new) if new_cost < cur_cost: anchor_take = anchor_take_new cur_cost = new_cost imax -= 1 while cur_cost != 0: for i in xrange(n): anchor_take_new = list(anchor_take) anchor_take_new[i] = None new_cost = cost(anchor_take_new) if new_cost < cur_cost: anchor_take = anchor_take_new cur_cost = new_cost break anchor_strs = ['BL', 'TR', 'TL', 'BR'] for i in xrange(n): ianchor = anchor_take[i] if ianchor is not None: anchor = anchor_strs[ianchor] yoff = [-sy[i], sy[i]][anchor[0] == 'B'] xoff = [-sx[i], sx[i]][anchor[1] == 'L'] row = (lons[i], lats[i], fontsize, 0, 1, anchor, texts[i]) self.gmt.pstext(in_rows=[row], D='%gp/%gp' % (xoff, yoff), *self.jxyr, **styles[i])