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

Drawing rectangles #392

Closed
Nasuyo opened this issue Jan 20, 2020 · 11 comments · Fixed by #1325
Closed

Drawing rectangles #392

Nasuyo opened this issue Jan 20, 2020 · 11 comments · Fixed by #1325
Assignees
Labels
bug Something isn't working documentation Improvements or additions to documentation upstream Bug or missing feature of upstream core GMT
Milestone

Comments

@Nasuyo
Copy link

Nasuyo commented Jan 20, 2020

Hello,

When trying to plot (fig.plot()) rectangles, basically nothing happens..^^
Following code -- with squres -- works:

fig = pygmt.Figure()
fig.coast(region=[0, 26, 44, 62], projection='S13/90/6i', frame="ag", shorelines="0.3p,black", borders="1/0.5p,black")
fig.plot(10, 50, style='s1')
fig.show()

This should do the exact same thing, shouldn't it?:

fig = pygmt.Figure()
fig.coast(region=[0, 26, 44, 62], projection='S13/90/6i', frame="ag", shorelines="0.3p,black", borders="1/0.5p,black")
fig.plot(10, 50, style='r1/1')
fig.show()

Problem: No rectangle is drawn. Alterations fomo the style command like 'r1', 'r1,1', 'r1c', 'r1c/1c' etc. neither work.

Problem 2: Substituting r by R for a rounded rectangle produces an error:

Module 'psconvert' failed with status code 78:
psconvert [ERROR]: System call [gs -q -dSAFER -dNOPAUSE -dBATCH -sDEVICE=bbox -DPSL_no_pagefill -dMaxBitmap=2147483647 -dUseFastColor=true '/home/schroeder/.gmt/sessions/gmt6.20169/gmt_124.ps-' 2> '/home/schroeder/.gmt/sessions/gmt6.20169/psconvert_20169c.bb'] returned error 256.

I'm not sure whether this is actually a bug or just my own lack of knowledge.

Thanks in advance,
Stefan

@weiji14 weiji14 added the bug Something isn't working label Mar 11, 2020
@weiji14
Copy link
Member

weiji14 commented Mar 11, 2020

Hi Nasuyo,

Sorry for the really late reply, only got back into the flow quite recently 😳. I've had a look at the code and you're right, it only works with squares because you can pass a size argument directly into the style (e.g. style='s1' for a square of size 1). For rectangles it's a bit harder as GMT requires the length and width to be in the data column (rather than as you tried, 'r1/1'). See also https://docs.generic-mapping-tools.org/latest/plot.html#s.

One solution I can think of at the moment would be to put your x, y, length, width numbers into a textfile, and call something like pygmt.plot(data="file.txt", style="r"). Ideally though, we'll need to fix the relevant code here

@fmt_docstring
@use_alias(
R="region",
J="projection",
B="frame",
S="style",
G="color",
W="pen",
i="columns",
l="label",
C="cmap",
)
@kwargs_to_strings(R="sequence", i="sequence_comma")
def plot(self, x=None, y=None, data=None, sizes=None, direction=None, **kwargs):
"""
Plot lines, polygons, and symbols on maps.
Used to be psxy.
Takes a matrix, (x,y) pairs, or a file name as input and plots lines,
polygons, or symbols at those locations on a map.
Must provide either *data* or *x* and *y*.
If providing data through *x* and *y*, *color* (G) can be a 1d array
that will be mapped to a colormap.
If a symbol is selected and no symbol size given, then psxy will
interpret the third column of the input data as symbol size. Symbols
whose size is <= 0 are skipped. If no symbols are specified then the
symbol code (see *S* below) must be present as last column in the
input. If *S* is not used, a line connecting the data points will be
drawn instead. To explicitly close polygons, use *L*. Select a fill
with *G*. If *G* is set, *W* will control whether the polygon outline
is drawn or not. If a symbol is selected, *G* and *W* determines the
fill and outline/no outline, respectively.
Full option list at :gmt-docs:`plot.html`
{aliases}
Parameters
----------
x, y : float or 1d arrays
The x and y coordinates, or arrays of x and y coordinates of the
data points
data : str or 2d array
Either a data file name or a 2d numpy array with the tabular data.
Use option *columns* (i) to choose which columns are x, y, color,
and size, respectively.
sizes : 1d array
The sizes of the data points in units specified in *style* (S).
Only valid if using *x* and *y*.
direction : list of two 1d arrays
If plotting vectors (using ``style='V'`` or ``style='v'``), then
should be a list of two 1d arrays with the vector directions. These
can be angle and length, azimuth and length, or x and y components,
depending on the style options chosen.
{J}
{R}
A : bool or str
``'[m|p|x|y]'``
By default, geographic line segments are drawn as great circle
arcs. To draw them as straight lines, use *A*.
{B}
{CPT}
D : str
``'dx/dy'``: Offset the plot symbol or line locations by the given
amounts dx/dy.
E : bool or str
``'[x|y|X|Y][+a][+cl|f][+n][+wcap][+ppen]'``.
Draw symmetrical error bars.
{G}
S : str
Plot symbols (including vectors, pie slices, fronts, decorated or
quoted lines).
{W}
{U}
l : str
Add a legend entry for the symbol or line being plotted.
"""
kwargs = self._preprocess(**kwargs)
kind = data_kind(data, x, y)
extra_arrays = []
if "S" in kwargs and kwargs["S"][0] in "vV" and direction is not None:
extra_arrays.extend(direction)
if "G" in kwargs and not isinstance(kwargs["G"], str):
if kind != "vectors":
raise GMTInvalidInput(
"Can't use arrays for color if data is matrix or file."
)
extra_arrays.append(kwargs["G"])
del kwargs["G"]
if sizes is not None:
if kind != "vectors":
raise GMTInvalidInput(
"Can't use arrays for sizes if data is matrix or file."
)
extra_arrays.append(sizes)
with Session() as lib:
# Choose how data will be passed in to the module
if kind == "file":
file_context = dummy_context(data)
elif kind == "matrix":
file_context = lib.virtualfile_from_matrix(data)
elif kind == "vectors":
file_context = lib.virtualfile_from_vectors(
np.atleast_1d(x), np.atleast_1d(y), *extra_arrays
)
with file_context as fname:
arg_str = " ".join([fname, build_arg_string(kwargs)])
lib.call_module("plot", arg_str)

Alternatively, if you know the West/South/East/North coordinates of your area of interest, you can supply them directly and use style="r+s" like so:

import numpy as np
import pygmt

fig = pygmt.Figure()
fig.coast(region=[0, 26, 44, 62], projection='S13/90/6i', frame="ag", shorelines="0.3p,black", borders="1/0.5p,black")
fig.plot(data=np.array([[5,47,15,52]]), style='r+s', pen="3p,yellow")
fig.show()

gives:
Yellow rectangle drawn using pygmt

@weiji14 weiji14 added the question Further information is requested label Mar 11, 2020
@seisman
Copy link
Member

seisman commented Sep 13, 2020

FYI, GMT recently allows specifying rectangle's width and height from command line in GenericMappingTools/gmt#4164. It will be available in GMT 6.2.0.

Before that, the rectangle width and height must be given from the input data.

@maxrjones
Copy link
Member

I just tested this with the development version of gmt (6.2.0_d8a7766_2021.02.11).

This now produces a rectangle:

fig = pygmt.Figure()
fig.coast(region=[0, 26, 44, 62], projection='S13/90/6i', frame="ag", shorelines="0.3p,black", borders="1/0.5p,black")
fig.plot(10, 50, style='r1/2')
fig.show()

And the rounded rectangle style produced an error because the corner radius is required. This works for a rounded rectangle:

fig = pygmt.Figure()
fig.coast(region=[0, 26, 44, 62], projection='S13/90/6i', frame="ag", shorelines="0.3p,black", borders="1/0.5p,black")
fig.plot(10, 50, style='R1/2/0.5')
fig.show()

Does the issue stay open until GMT 6.2 is released or does it get closed as soon as the problem is fixed in the main gmt branch?

@seisman
Copy link
Member

seisman commented Feb 11, 2021

We will keep the issue open until we bump the minimum required GMT version to 6.2.0 in PyGMT v0.4.0.

@maxrjones
Copy link
Member

maxrjones commented Feb 11, 2021

Would it be possible to use a label for these types of issues (i.e., upstream problems that are solved but require an update to the minimum required GMT version)? In reading through PyGMT issues, it appears there are at least a couple of this type of issue currently open. I think a tag would help for keeping track and quickly identifying which issues do not require any action.

@weiji14 weiji14 added this to the 0.4.0 milestone Feb 11, 2021
@weiji14
Copy link
Member

weiji14 commented Feb 11, 2021

Would it be possible to use a label for these types of issues (i.e., upstream problems that are solved but require an update to the minimum required GMT version)? In reading through PyGMT issues, it appears there are at least a couple of this type of issue currently open. I think a tag would help for keeping track and quickly identifying which issues do not require any action.

Yeah there are quite a few of these. I think labeling it 'upstream' and adding it to the v0.4.0 milestone should suffice, but feel free to suggest a new label.

@maxrjones maxrjones added the upstream Bug or missing feature of upstream core GMT label Feb 11, 2021
@weiji14 weiji14 added documentation Improvements or additions to documentation and removed question Further information is requested labels Jun 2, 2021
@weiji14
Copy link
Member

weiji14 commented Jun 2, 2021

I just tested this with the development version of gmt (6.2.0_d8a7766_2021.02.11).

This now produces a rectangle:

fig = pygmt.Figure()
fig.coast(region=[0, 26, 44, 62], projection='S13/90/6i', frame="ag", shorelines="0.3p,black", borders="1/0.5p,black")
fig.plot(10, 50, style='r1/2')
fig.show()

And the rounded rectangle style produced an error because the corner radius is required. This works for a rounded rectangle:

fig = pygmt.Figure()
fig.coast(region=[0, 26, 44, 62], projection='S13/90/6i', frame="ag", shorelines="0.3p,black", borders="1/0.5p,black")
fig.plot(10, 50, style='R1/2/0.5')
fig.show()

Does the issue stay open until GMT 6.2 is released or does it get closed as soon as the problem is fixed in the main gmt branch?

Perhaps add a new gallery example to mention the style='r1/2' way of drawing rectangles? Then we can close this issue.

@core-man
Copy link
Member

core-man commented Jun 2, 2021

Perhaps add a new gallery example to mention the style='r1/2' way of drawing rectangles? Then we can close this issue.

Could I help with this example?

@weiji14
Copy link
Member

weiji14 commented Jun 2, 2021

Perhaps add a new gallery example to mention the style='r1/2' way of drawing rectangles? Then we can close this issue.

Could I help with this example?

Yes please, go for it! I'll assign this issue to you @core-man.

@seisman
Copy link
Member

seisman commented Jun 3, 2021

Please note that we already have an example for rectangles (https://www.pygmt.org/latest/gallery/symbols/multi_parameter_symbols.html), but in this example we read the "sizes" from the input file, rather than in the style parameter.

I feel we can simply update that example, rather than adding a new gallery example.

@Nasuyo
Copy link
Author

Nasuyo commented Jun 7, 2021 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working documentation Improvements or additions to documentation upstream Bug or missing feature of upstream core GMT
Projects
None yet
5 participants