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

plot(x, y, G=value, C=cmap) gives strange behavior for individual points #417

Closed
kmaterna opened this issue Apr 16, 2020 · 5 comments
Closed
Labels
triage Unsure where this issue fits

Comments

@kmaterna
Copy link
Contributor

Description of the problem

In plot(), using G=value and C=cmap to interpret a color from a CMAP for a single value doesn't work in the same way that a list/array of values does. Interpreting a single value from a color map would be useful for plotting a bunch polygons with different colors (ex: for coulomb stress changes on fault segments).

  • For plotting arrays of points, G returns an array of colors extracted from the cmap, as it should
  • For plotting single polygons, G returns foreground or background color. wrong?
  • For plotting single points, G returns 0. wrong?
    In the single-element case, plot() requires G=str, which is also counter-intuitive.

Either way, the result makes it difficult to plot custom-colored polygons with a colormap
(usually I would just extract a color for each polygon and plot each one separately, calling plot() in a loop). Is there another way to plot polygons with cmap colors?

In the example code, I'm plotting some dummy data, once as an array of points, and once in a for-loop with points and polygons in individual plot() calls. The cmap behavior is quite different.

Full code that generated the error

import pygmt
# Make CPT and Fake Data
pygmt.makecpt(C="jet",T="-1.0/1.0/0.05",H="mycpt.cpt");
xdata = [-123, -122.5, -122.0, -121.5]; 
ydata = [36.5, 37, 37.5, 38]; 
zdata = [-0.7, -0.25, 0.25, 0.7];

#  Batch Calling : works
fig = pygmt.Figure()
title="+t\"Batch to CMAP - Works for Points.\""; 
fig.coast(region=[-124, -120, 35, 39], projection="M7i", B=[title,"1.0"],shorelines="1.0p,black"); 
fig.colorbar(D="jBr+w3.5i/0.2i+o5.5c/1.5c+h",C="mycpt.cpt",I="0.8",G="-1.0/1.0",B=["x"+str(0.2),"y+L\"KPa\""]); 
fig.plot(x=xdata, y=ydata, color=zdata, style="c1.8c", pen="thick,black", C="mycpt.cpt"); 
fig.savefig("Working.png");

#  Single Calls Only : doesn't do the right thing
fig = pygmt.Figure()
title="+t\"Single Calls to CMAP - Odd.\""; 
fig.coast(region=[-124, -120, 35, 39],projection="M7i",shorelines="1.0p,black",B=[title,"1.0"]); 
fig.colorbar(D="jBr+w3.5i/0.2i+o5.5c/1.5c+h",C="mycpt.cpt",I="0.8",G="-1.0/1.0",B=["x"+str(0.2),"y+L\"KPa\""]); 
for i in range(len(xdata)):  # just looping through the data
	fig.plot(x=xdata[i], y=ydata[i], G=str(zdata[i]), style="c1.8c", pen="thick,black", C="mycpt.cpt");  # plotting a point with associated cmap data
	xdata_long = [xdata[i]+0.2, xdata[i]+0.3, xdata[i]+0.3, xdata[i]+0.2, xdata[i]+0.2];  # building a polygon
	ydata_long = [ydata[i], ydata[i], ydata[i]+0.1, ydata[i]+0.1, ydata[i]];  # building a polygon
	fig.plot(x=xdata_long, y=ydata_long, G=str(zdata[i]), pen="thick,black", C="mycpt.cpt");  # plotting the polygon with associated cmap data
fig.savefig("Not_Working.png");

System information
Mac OSX Mojave, miniconda3 package manager, python3.6. I installed pygmt in a brand new python environment today.

Working

Not_Working

@welcome
Copy link

welcome bot commented Apr 16, 2020

👋 Thanks for opening your first issue here! Please make sure you filled out the template with as much detail as possible. You might also want to take a look at our contributing guidelines and code of conduct.

@weiji14 weiji14 added the triage Unsure where this issue fits label Apr 17, 2020
@weiji14
Copy link
Member

weiji14 commented Apr 17, 2020

Right, bear with me for a little bit while I get my head around this. I think this is similar to the problem we had in #376.

To colour your points in the for-loop, the G argument needs to be given a list instead of a str (which is inconsistent with the documentation). I.e. G=[zdata[i]].

Edit: To colour the polygon, you can set the Z argument to something like Z="f0.7" which would base the fill colour of the polygon on your provided cpt. I've updated the code below.

#  Single Calls Only : doesn't do the right thing
fig = pygmt.Figure()
title="+t\"Single Calls to CMAP - Odd.\""; 
fig.coast(region=[-124, -120, 35, 39],projection="M7i",shorelines="1.0p,black",B=[title,"1.0"]); 
fig.colorbar(D="jBr+w3.5i/0.2i+o5.5c/1.5c+h",C="mycpt.cpt",I="0.8",G="-1.0/1.0",B=["x"+str(0.2),"y+L\"KPa\""]); 
for i in range(len(xdata)):  # just looping through the data
	fig.plot(x=xdata[i], y=ydata[i], G=[zdata[i]], style="c1.8c", pen="thick,black", C="mycpt.cpt");  # plotting a point with associated cmap data
	xdata_long = [xdata[i]+0.2, xdata[i]+0.3, xdata[i]+0.3, xdata[i]+0.2, xdata[i]+0.2];  # building a polygon
	ydata_long = [ydata[i], ydata[i], ydata[i]+0.1, ydata[i]+0.1, ydata[i]];  # building a polygon
	fig.plot(x=xdata_long, y=ydata_long, pen="thick,black", C="mycpt.cpt", Z="f" + str(zdata[i]));  # plotting the polygon with associated cmap data
fig.savefig("Somewhat_Working.png");

produces:

Somewhat_Working

I'll need to work out how to colour a filled polygon, let me go and have lunch first :) Still, I think we might need to extend the fix in #376 to include G/color as well, or change the documentation to make it clear, or do both.

@kmaterna
Copy link
Contributor Author

Thank you so much for your quick reply- this is exactly it! 🎉🎉🎉
I guess this is like the -Zval in GMT, but I would have had trouble figuring this one out on my own. Thanks!!

@weiji14
Copy link
Member

weiji14 commented Apr 18, 2020

Yes it does get a bit confusing, but glad it helped. The -Z syntax seems to be new in GMT 6.0.0, and it might change in GMT 6.1.0 (see GenericMappingTools/gmt/issues/3131 for context) to make colouring the fill and outline more intuitive.

I'll leave this issue open for now until we clear up the plot documentation.

@weiji14
Copy link
Member

weiji14 commented Feb 17, 2021

Documentation for plot has been revised significantly in PyGMT v0.3.0 (see https://www.pygmt.org/v0.3.0/api/generated/pygmt.Figure.plot.html) which uses GMT 6.1.1, and long alias zvalue (Z) was added in #666. It might still be a bit confusing getting to know how color (-G) and zvalue (-Z) works, but I'll close this issue now and we can open up a fresh issue later (if there's demand) to add a gallery example for using -G/-Z in plot to colour individual points.

@weiji14 weiji14 closed this as completed Feb 17, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
triage Unsure where this issue fits
Projects
None yet
Development

No branches or pull requests

2 participants