GenericMappingTools / pygmt

A Python interface for the Generic Mapping Tools.
https://www.pygmt.org
BSD 3-Clause "New" or "Revised" License
747 stars 216 forks source link

plot crashes when plotting arrows #406

Closed seisman closed 4 years ago

seisman commented 4 years ago

Description of the problem

I'm trying to plot two vectors using the following script. It works well if pen is set to 1p,black (i.e. a simple line), but crashes if set to 1p,black+ve0.2c. Actually, the first plot works, but the second one crashes.

Full code that generated the error

import pygmt
import numpy as np

fig = pygmt.Figure()
fig.basemap(projection="X15c/10c", region="400/600/5/8", frame=True)
fig.plot(x=[530.0, 530.0], y=[6.0, 7.0], pen='1p,black+ve0.2c')
fig.plot(x=[570.0, 570.0], y=[6.0, 7.0], pen='1p,black+ve0.2c')
fig.savefig("map.pdf")

Full error message

python(64354,0x11ac3bdc0) malloc: *** error for object 0x7f8f28e50900: pointer being freed was not allocated
python(64354,0x11ac3bdc0) malloc: *** set a breakpoint in malloc_error_break to debug
[1]    64354 abort      python test.py

System information

output of conda list
PASTE OUTPUT OF CONDA LIST HERE
weiji14 commented 4 years ago

I can reproduce the same crash, with GMT 6.0 on Linux and using the pygmt master branch. The corresponding code in GMT works though:

gmt begin test png
gmt basemap -JX15c/10c -R400/600/5/8 -B
gmt plot -W1p,black+ve0.2c << EOF
530.0 6.0
530.0 7.0
EOF
gmt plot -W1p,black+ve0.2c << EOF
570.0 6.0
570.0 7.0
EOF
gmt end show

produces:

two vertical lines plotted successfully using gmt

Not much of a clue as to why it's crashing though :man_shrugging:

d-murashkin commented 4 years ago

Also crushes on the second plot, but does not crush if integer values are used. That is

import pygmt
import numpy as np

fig = pygmt.Figure()
fig.basemap(projection="X15c/10c", region="400/600/5/8", frame=True)
fig.plot(x=[530, 530], y=[6.0, 7.0], pen='1p,black+ve0.2c')
fig.plot(x=[570, 570], y=[6.0, 7.0], pen='1p,black+ve0.2c')
fig.savefig("map.pdf")

works fine

fig.plot(x=[530, 530], y=[6.0, 7.0], pen='1p,black+ve0.2c')
fig.plot(x=[570.0, 570.0], y=[6.0, 7.0], pen='1p,black+ve0.2c')

also works fine

fig.plot(x=[530.0, 530.0], y=[6.0, 7.0], pen='1p,black+ve0.2c')
fig.plot(x=[570, 570], y=[6.0, 7.0], pen='1p,black+ve0.2c')

does not work

Seems like the issue is related to floating point numbers, also the data for later plots is converted to the data type of the first plot.

d-murashkin commented 4 years ago

I might have found a solution: convert all floating point numbers to float32 (float64 is default) The following works with no error:

import pygmt
import numpy as np

fig = pygmt.Figure()
fig.basemap(projection="X15c/10c", region="400/600/5/8", frame=True)
fig.plot(x=[np.float32(530.0), np.float32(530.0)], y=[6.0, 7.0], pen='1p,black+ve0.2c')
fig.plot(x=[np.float32(570.0), np.float32(570.0)], y=[6.0, 7.0], pen='1p,black+ve0.2c')
fig.savefig("map.pdf")

Could it be that GMT does not have good support for float64 and uses float32 by default? Anyway, for plotting float64 values are probably not needed, so all float64 data should probably converted to float32 in the wrapper.