Problem with calling a dataframe and using it on fig.plot(style)

I’ve been trying to plot vertical displacements on a bird’s eye view map, with positive measurements shown by up arrows and negative displacements.

One solution I thought of was to put two additional columns in my CSV file, ‘sty’ and ‘pen’, which would change depending on the value of the displacement. ‘Sty’ contains the actual formatting options for the style parameter in fig.plot while ‘pen’ contains the formatting options for the pen parameter in the same command. This is achieved by doing an if-else command inside Excel, so no worries about this. Then I will call each column to the corresponding parameter (i. e. fig.plot(x=df.x,y=df.y,style=df.sty,pen=df.pen).

However, GMT doesn’t accept multiple style and pen options in one command, so what I did was to make a loop where the pd.read_csv command will only read one line at a time and then proceed to the next line after reading and plotting the previous one. This actually worked except for the style parameter. It seems that it has a different way of reading the options from a variable. I know calling the variable for pen works (pen=df.pen) because I tried to use a constant set of parameters for style and the vectors were plotted. The colors of the arrows are red if the displacement is positive and blue if it’s not. However, the arrowheads were constant because I can only make it work with constant style parameters.

Can anyone please help me on this? Thanks.

The barebones script is as follows:

import pygmt
import numpy as np
import pandas as pd

fig = pygmt.Figure()
region = [120.448, 120.451, 22.874, 22.876]
fig.basemap(region=region, projection="M15c", frame=["WSrt","a0.001"],rose=["x5.5i/3i+w0.75i+l,,,N"],map_scale=["x5.3i/0.2i+w20e+l"])
dtype = {"lon":float,"lat":float,"azi":float,"mag":float,"sty":str,"pen":str}
for i in range(len(df.index)):
    i = i+1

problem.dat (1.8 KB)

Hello @listwanites,

I think it is not needed to load the data within the for loop line by line. You can load the complete data into a pandas dataframe and iterate through it line by line.
Please note that the direction parameter is specified by a list of two 1-D arrays structured as [[angle_in_degrees], [length]].
The i = i+1 at the end of the for loop is probably not needed, as the iteration is done already by the for loop.
With these changes of your code examples, there is the output figure shown below.

import pygmt
import pandas as pd

region = [120.448, 120.451, 22.874, 22.876]

dtype = {
    "lon":float, "lat":float, "azi":float, "mag":float, "sty":str, "pen":str,
df = pd.read_csv(
    "style.dat" ,names=["lon","lat","mag","azi","sty","pen"], dtype=dtype, header=0,

fig = pygmt.Figure()
fig.basemap(region=region, projection=projection, frame=["WSrt", "a0.001"])

for i in range(len(df)):
        x=df.loc[i, "lon"],
        y=df.loc[i, "lat"],
        direction=[[df.loc[i, "mag"]], [df.loc[i, "azi"]]],
        style=df.loc[i, "sty"],
        pen=df.loc[i, "pen"],
# fig.savefig(fname="plot_arrows_varying_style.png")



Thanks for the help. You made a more efficient code. I never though loc would work for this situation.