Coloring ellipses based on dataframe column

Hi all,

I want to color come ellipses based on a float value column (called ‘Minor’) in my dataframe (‘df380’):

   pygmt.makecpt(cmap="viridis", series=[df380.Minor.min(), df380.Minor.max()])
   fig.plot(data=df380, style="e", cmap=True, color=df380.Minor, pen="0p,black")

But this generates the following error:

GMTInvalidInput: Can't use arrays for color if data is matrix or file.

I can’t tell what’s going wrong here compared to other working examples online. Any help appreciated!

Tom

Hi Tom,

Coloring of points based on a value can only be done if you input data via x and y, e.g. using something like:

fig.plot(x=df380.longitude, y=df380.latitude, style="e", cmap=True, color=df380.Minor, pen="0p,black")

assuming that your x and y columns are named ‘longitude’ and ‘latitude’ respectively. The GMTInvalidInput error you are getting is because you are passing in a matrix-type pandas.DataFrame via the data parameter. Let us know if that helps, and if not, maybe post the output of df380.head() so that we can inspect a sample of your dataframe and help to reproduce your issue.

Thanks for the suggestion, but that actually produces a blank plot (no error, just a blank figure). I guess that’s because there is no input to say what the direction + minor and major axes of the ellipses are, whereas simply stating data = df will automatically find those parameters for you, so long as your dataframe is in the right format.

For reference, here is the output of df380.head():

Longitude Latitude azimuth Major Minor
1 143.890395 -39.836134 86.690006 0.991056 0.915180
2 143.631681 -38.845903 -88.008732 0.994992 0.957652
3 144.163615 -39.269567 89.187011 0.986036 0.921038
4 144.432449 -38.702371 -78.331177 0.982666 0.909278
5 144.697050 -38.134570 -57.902771 1.017184 0.806435

Ah right, ellipses, should have read more closely! In this case, you might want to try the new pygmt.Figure.velo function. It’s not available in the stable PyGMT v0.3.1 release, so you’ll need to install the PyGMT development version to use it:

pip install --pre --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple pygmt

after that, you should be able to use fig.velo. The specification (spec) is a bit hardcoded, so you might need to reorder your pandas.DataFrame columns to be in the right order ( 1,2: longitude, latitude 3,4: eastward, northward velocity 5,6: semi-major, semi-minor axes). I had to make up some data for the Eastward/Northward columns to get the example below to work.

df380 = pd.DataFrame(
    data={
        "Longitude": [143.890395, 143.631681, 144.163615, 144.432449, 144.697050],
        "Latitude": [-39.836134, -38.845903, -39.269567, -38.702371, -38.134570],
        "Eastward": [0.5, 0.5, 0.5, 0.5, 0.5],  # change this made up data
        "Northward": [0.75, 0.75, 0.75, 0.75, 0.75],  # change this made up data
        "Major": [0.991056, 0.994992, 0.986036, 0.982666, 1.017184],
        "Minor": [0.915180, 0.957652, 0.921038, 0.909278, 0.806435],
        "azimuth": [86.690006, -88.008732, 89.187011, -78.331177, -57.902771],
    }
)

fig = pygmt.Figure()
fig.velo(
    data=df380,
    spec="r0.5/0.95",
    pen="0.6p,red",
    uncertaintycolor="lightblue1",
    frame=True,
)
fig.savefig(fname="ellipses.png")
fig.show()

which produces:

Hopefully the code above will be enough to get you started. Let us know if you need any clarification, it would be great to get feedback on the velo function actually before we release it officially in PyGMT v0.4.0 (sometime in June 2021 perhaps).

References:

Ahhh that looks promising. To be honest, in the meantime since asking this question I devised a solution that worked for my purposes in QGIS, but next time I am doing similar work I will try this.

Thank you for the wonderful help!

1 Like