Repository: obspy/obspy

Issue:
obspy.taup.tau.Arrivals.plot_rays: color of ray paths 
ObsPy version: 1.1.0
Python version: 3.6
Platform: OsX and Anaconda

Hi, 

I'm plotting 3 phases ["PcPPcPPKP", "PcPPKPPcP", "PKPPcPPcP"], which have similar ray path, using obspy.taup.tau.Arrivals.plot_rays. Since they are all plotted in the same color, it's difficult to distinguish them. However, there is no option in that function to change the color of the ray paths. Is there a way to do that?

![Raypath_cKK](https://user-images.githubusercontent.com/32896474/66133769-85717980-e5f7-11e9-94d1-b184e3af2cb0.png)

Thank you in advance.


Discussion:
Please provide the code you are using like it asks in the template.
I'm sorry that I forgot to attach the code.

```
import math
import matplotlib.pyplot as plt
from obspy.taup import TauPyModel
from obspy.geodetics.base import gps2dist_azimuth  
from obspy.geodetics import kilometers2degrees 

def plot_phasepath(model, lat_event, lon_event, dep_event, lat_sta, lon_sta, phases, arrival=False, plot=False):
    model_ev = TauPyModel(model=model)
    dist, azi, bazi = gps2dist_azimuth(lat_event, lon_event, lat_sta, lon_sta)
    dist_deg        = kilometers2degrees(dist/1000.)

    arr_path = model_ev.get_ray_paths(source_depth_in_km=dep_event, distance_in_degree=dist_deg, phase_list=phases)

    if arrival:
        print(dist_deg)
        print(arr_path)

    arr_path.plot_rays()
    plt.legend(loc="center", bbox_to_anchor=(1.0, 0.045),fontsize="xx-large")
    if plot:
        plt.savefig('Raypath.png', dpi=180)

# Background model
model = "iasp91" 

# Event parameter
lat_event = 51.423
lon_event = 178.026
dep_event = 33.9

# station location
lat_sta = 46.
lon_sta = 10.

# List of phases
phases = ['PcPPcPPKP','PcPPKPPcP','PKPPcPPcP']

# Plot the phase path
plot_phasepath(model, lat_event, lon_event, dep_event, lat_sta, lon_sta, phases, arrival=False, plot=True)
```
It may be a limitation how the colour (cycle) is called in the source code
for the plotting function:

from obspy.taup import TauPyModel
model = TauPyModel(model="iasp91")
arrivals = model.get_ray_paths(source_depth_in_km=500,
distance_in_degree=130, phase_list=["ttbasic"])
ax = arrivals.plot_rays(legend=True)

also results in (some) different arrivals with the same colour.



On Fri, 4 Oct 2019 at 05:03, Angel Ling <notifications@github.com> wrote:

> I'm sorry that I forgot to attach the code.
>
> import math
> import matplotlib.pyplot as plt
> from obspy.taup import TauPyModel
> from obspy.geodetics.base import gps2dist_azimuth
> from obspy.geodetics import kilometers2degrees
>
> def plot_phasepath(model, lat_event, lon_event, dep_event, lat_sta, lon_sta, phases, arrival=False, plot=False):
>     model_ev = TauPyModel(model=model)
>     dist, azi, bazi = gps2dist_azimuth(lat_event, lon_event, lat_sta, lon_sta)
>     dist_deg        = kilometers2degrees(dist/1000.)
>
>     arr_path = model_ev.get_ray_paths(source_depth_in_km=dep_event, distance_in_degree=dist_deg, phase_list=phases)
>
>     if arrival:
>         print(dist_deg)
>         print(arr_path)
>
>     arr_path.plot_rays()
>     plt.legend(loc="center", bbox_to_anchor=(1.0, 0.045),fontsize="xx-large")
>     if plot:
>         plt.savefig('Raypath.png', dpi=180)
>
> # Background model
> model = "iasp91"
>
> # Event parameter
> lat_event = 51.423
> lon_event = 178.026
> dep_event = 33.9
>
> # station location
> lat_sta = 46.
> lon_sta = 10.
>
> # List of phases
> phases = ['PcPPcPPKP','PcPPKPPcP','PKPPcPPcP']
>
> # Plot the phase path
> plot_phasepath(model, lat_event, lon_event, dep_event, lat_sta, lon_sta, phases, arrival=False, plot=True)
>
> —
> You are receiving this because you are subscribed to this thread.
> Reply to this email directly, view it on GitHub
> <https://github.com/obspy/obspy/issues/2470?email_source=notifications&email_token=ABG3TXW2BJDAOMLEEEIMOP3QMYJSVA5CNFSM4I5D2AEKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEAIWGNI#issuecomment-538010421>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/ABG3TXVQKL25RZDNWHT42PTQMYJSVANCNFSM4I5D2AEA>
> .
>


Resolving patch:
diff --git a/obspy/taup/tau.py b/obspy/taup/tau.py
--- a/obspy/taup/tau.py
+++ b/obspy/taup/tau.py
@@ -300,6 +300,15 @@ def plot_rays(self, phase_list=None, plot_type="spherical",
         if phase_list is None:
             phase_list = ("ttall",)
 
+        requested_phase_names = parse_phase_list(phase_list)
+        requested_phase_name_map = {}
+        i = 0
+        for phase_name in requested_phase_names:
+            if phase_name in requested_phase_name_map:
+                continue
+            requested_phase_name_map[phase_name] = i
+            i += 1
+
         phase_names = sorted(parse_phase_list(phase_list))
         arrivals = []
         for arrival in self:
@@ -346,17 +355,22 @@ def plot_rays(self, phase_list=None, plot_type="spherical",
 
             intp = matplotlib.cbook.simple_linear_interpolation
             radius = self.model.radius_of_planet
+            phase_names_encountered = {ray.name for ray in arrivals}
+            colors = {
+                name: COLORS[i % len(COLORS)]
+                for name, i in requested_phase_name_map.items()}
+            i = len(colors)
+            for name in sorted(phase_names_encountered):
+                if name in colors:
+                    continue
+                colors[name] = COLORS[i % len(COLORS)]
+                i += 1
             for ray in arrivals:
-                if ray.name in phase_names:
-                    # Requires interpolation,or diffracted phases look funny.
-                    ax.plot(intp(ray.path["dist"], 100),
-                            radius - intp(ray.path["depth"], 100),
-                            color=COLORS[phase_names.index(ray.name) %
-                                         len(COLORS)], label=ray.name, lw=2.0)
-                else:
-                    ax.plot(intp(ray.path["dist"], 100),
-                            radius - intp(ray.path["depth"], 100),
-                            color='k', label=ray.name, lw=2.0)
+                color = colors.get(ray.name, 'k')
+                # Requires interpolation,or diffracted phases look funny.
+                ax.plot(intp(ray.path["dist"], 100),
+                        radius - intp(ray.path["depth"], 100),
+                        color=color, label=ray.name, lw=2.0)
                 ax.set_yticks(radius - discons)
                 ax.xaxis.set_major_formatter(plt.NullFormatter())
                 ax.yaxis.set_major_formatter(plt.NullFormatter())
diff --git a/obspy/taup/utils.py b/obspy/taup/utils.py
--- a/obspy/taup/utils.py
+++ b/obspy/taup/utils.py
@@ -24,7 +24,7 @@ def parse_phase_list(phase_list):
     for phase_name in phase_list:
         phase_names += get_phase_names(phase_name)
     # Remove duplicates.
-    return list(set(phase_names))
+    return sorted(list(set(phase_names)))
 
 
 def get_phase_names(phase_name):


Test patch:
diff --git a/obspy/taup/tests/images/spherical_diff_phases.png b/obspy/taup/tests/images/spherical_diff_phases.png
Binary files a/obspy/taup/tests/images/spherical_diff_phases.png and b/obspy/taup/tests/images/spherical_diff_phases.png differ
diff --git a/obspy/taup/tests/images/spherical_many_phases.png b/obspy/taup/tests/images/spherical_many_phases.png
Binary files a/obspy/taup/tests/images/spherical_many_phases.png and b/obspy/taup/tests/images/spherical_many_phases.png differ
diff --git a/obspy/taup/tests/images/spherical_many_phases_one_way.png b/obspy/taup/tests/images/spherical_many_phases_one_way.png
Binary files a/obspy/taup/tests/images/spherical_many_phases_one_way.png and b/obspy/taup/tests/images/spherical_many_phases_one_way.png differ