michaelgrund / GMT-plotting

Collection of GMT (Generic Mapping Tools) scripts, jupyter notebooks (using PyGMT) and files (including digitized map content, colormaps, grid files etc.)
103 stars 27 forks source link

009_paper_GR2020/Figure S10: Wrong colormap set up in colorwheel #13

Open yvonnefroehlich opened 1 year ago

yvonnefroehlich commented 1 year ago

In Figure S10 (009_paper_GR2020), the colormap represented by the colorwheel does not match the color-coding used for the bars of the splits. The plots in the Supplementary Material of Grund & Ritter (2020) shown up on page 28 look correct. compare_SuppMat_JN_GR2020_FigS10

Suggestions to fix this issue This Jupyter Notebook seems not completely finished. However, maybe the code snippets below can serve as an orientations, in case further work on this JN is planed.

(1) Adjust colormap used for plotting the data points

(2) Adjust creation of colorwheel via Matplotlib

plot in polar projection, loop over the whole range 0 to 360 degrees

for ii in range(360):

backazimuth in seismology

# from North (0 deg)
ax.set_theta_offset(pi/2)
# clockwise, i.e. to East (90 deg)
ax.set_theta_direction(-1)
plt.polar(
    [theta[ii], theta[ii]], 
    rho, 
    color=[cmapa[0][ii], cmapa[1][ii], cmapa[2][ii]], 
    linewidth=2,
)

_(3) Use PyGMT instead of Matplotlib to create colorwheel_
- limitation: Running time of the code
```python
import pygmt

cmap_colorwheel = "romaO"
rho_min = 1.22
rho_max = 2

fig = pygmt.Figure()

pygmt.config(
    # make area outside of plot transparent
    PS_PAGE_COLOR="white@1",
    # make frame outline white
    MAP_FRAME_PEN="white",
)

fig.basemap(
    region=[0, 360, rho_min, rho_max],
    # geographic azimuth instead of standard angle
    # clockwise from North instead of counter-clockwise from East
    projection="P5c+a",
    frame="rltb",
)

pygmt.makecpt(
    cmap=cmap_colorwheel,
    cyclic=True,
    series=[0, 360, 1],
)

# takes some time
for i_ang in range(0,360,1):  # min, max], step
    rho = [rho_min, rho_max]
    fig.plot(
        x=[i_ang, i_ang],
        y=rho,
        zvalue=i_ang,
        pen="2p+z",
        cmap=True,
)

fig.show()

# fig.savefig(fname="colorwheel_N_cw_pygmt" + cmap_colorwheel + ".png")
# fig.savefig(fname="colorwheel_N_cw_pygmt" + cmap_colorwheel + ".eps")
# fig.savefig(fname="colorwheel_N_cw_pygmt" + cmap_colorwheel + ".pdf")
michaelgrund commented 1 year ago

Thanks @yvonnefroehlich for reporting this issue. Currently I'm revising all notebooks to update the required PyGMT/GMT versions, add missing content or fix issues, so your suggestions (hopefully) may be considered within the next few weeks :wink:.

yvonnefroehlich commented 12 months ago

An update on option 3 Using rotated rectangles (j) instead of lines solves the long-running time issue. This is because the color-coding is now applied to fill instead of pen and no loop is needed anymore (fill="+z" is not explicitly needed):

import numpy as np
import pygmt

# -----------------------------------------------------------------------------
# Select for your needs
# -----------------------------------------------------------------------------
# Scientific colourmaps by Fabio Crameri: romaO, bamO, brocO, corkO, vikO
# cmocean colormaps by Kristen M. Thyng: phase
cmap_colorwheel = "romaO"

rho_min = 1.0  # inner radius
rho_max = 2.5  # outer radius

# -----------------------------------------------------------------------------
# Set up rotated rectangle or bar data
# -----------------------------------------------------------------------------
# [[lon, lat, direction, width, height]]
# In polar coordinates lon refers to the angle and lat to the radius (rho)
# Location applies to the center of the bar -> shift by length/2
# Add quantity for fill color as second column (zero-based indexing)
# Direction of bar (j) is from North but still counter-clockwise -> negative sign
data_bars = np.zeros([360, 6])
for i_ang in range(0, 360, 1):  # min, max], step
    data_bars_temp = np.array([i_ang, rho_min+rho_max/2, i_ang, -i_ang, 0.05, rho_max-rho_min])
    data_bars[i_ang,:] = data_bars_temp

# -----------------------------------------------------------------------------
# Create colorwheel plot
# -----------------------------------------------------------------------------
fig = pygmt.Figure()

pygmt.config(
    # Make area outside of plot transparent
    PS_PAGE_COLOR="white@1",
    # Make frame outline white
    MAP_FRAME_PEN="white",
)

fig.basemap(
    region=[0, 360, 0, rho_max],
    # geographic azimuth instead of standard angle -> backazimuth
    # clockwise from North instead of counter-clockwise from East
    projection="P" + str(rho_max*2) + "c+a",
    frame="rltb",
)

# Create colormap for direction (backazimuth)
pygmt.makecpt(cmap=cmap_colorwheel, cyclic=True, series=[0, 360, 1])

# Plot rotated rectangles with color-coding for direction (backzimuth)
fig.plot(data=data_bars, style="j", cmap=True)

fig.show()

# fig.savefig(fname="colorwheel_N_cw_pygmt_bar_" + cmap_colorwheel + ".png")
# fig.savefig(fname="colorwheel_N_cw_pygmt" + cmap_colorwheel + ".eps")
# fig.savefig(fname="colorwheel_N_cw_pygmt" + cmap_colorwheel + ".pdf")
yvonnefroehlich commented 5 months ago

Again an update (2024/05/20) I am currently working on this colorwheel thing in https://github.com/yvonnefroehlich/gmt-pygmt-plotting/pull/23. After merging this PR, a python function for creating a colorwheel in PyGMT can be found at https://github.com/yvonnefroehlich/gmt-pygmt-plotting/tree/main/000_general_stuff/02_colorwheel.