Repository: obspy/obspy

Issue:
beachball plotting issues
* conda 4.5.11
* obspy 1.1.1
* python 3.7.1

Hello, the obspy beachball routines seem to plot some beachballs incorrectly. This may be related to numerical instabilities and large numbers mentioned before (#2114), but seems that small numbers can also cause issues. The following examples should all plot solid beachballs (+ISO)

command line
```
obspy-mopad plot -i USE 0.5774,0.5774,0.5774,0,0,0  # solid beachball
obspy-mopad plot -i USE 0.5774,0.5773,0.5774,0,0,0  # 0.0001 difference in one element
```

script
```
from obspy.imaging.beachball import beachball as bb1
from obspy.imaging.mopad_wrapper import beachball as bb2

mt1 = [3.258319e+16,  3.258250e+16,  3.258180e+16,  0.000000e+00,  0.000000e+00,  0.000000e+00]
mt2 = [3.258319    ,  3.258250    ,  3.258180    ,  0           ,  0           ,  0]

fig = bb1(mt1)  # strange beachball
fig = bb1(mt2)  # OK
fig = bb2(mt1)  # strange beachball
fig = bb2(mt2)  # strange beachball
```

right beachball
![rightbb](https://user-images.githubusercontent.com/5817670/56826953-bfc33780-685d-11e9-9603-9ff9f9a6dcdb.png)

strange beachball
![wrongbb](https://user-images.githubusercontent.com/5817670/56826968-c9e53600-685d-11e9-8aae-6295fb120d6f.png)

For reference the following dataset contains a broad range of mechanisms
https://github.com/carltape/compearth/blob/master/momenttensor/plot/gmt/beachball_plots/beachballs_ipts1_iref1_lune_psmeca
`[X, Y, depth, mrr, mtt, mff, mrt, mrf, mtf, exp]`

On an (X,Y) grid they should plot as the following figure
![bbcollection2](https://user-images.githubusercontent.com/5817670/56745788-4bb06300-677b-11e9-97c5-86a011cca7a5.jpg)




Discussion:
As a sanity check, each of the two example moment tensors (mt1, mt2) has three eigenvalues that are all positive. So the beachballs should be all solid. From other tests, it appears that the plotting issues extend beyond the all-solid beachball cases.
Unfortunately, we don't have anybody with a good overview of the existing beachball routines in obspy, I think. It was ported/integrated from [mopad](https://github.com/geophysics/MoPaD) but that is orphaned for several years as far as I can see.

So, I don't really know how to proceed with improving/fixing the current status. Are there other Python codes for beachballs plotting etc that we are not aware of?
see https://djpugh.github.io/MTfit/mtplot.html#beachball-plot
@megies the pyrocko beachball routines plot all the beachballs correctly (thanks @emolch)
https://pyrocko.org/docs/current/_modules/pyrocko/moment_tensor.html#MomentTensor
![bbpr](https://user-images.githubusercontent.com/5817670/57789536-69009d80-7739-11e9-8f3c-0e8cd50c9ca8.png)

at the moment the same dataset plotted with obspy looks like this
![bbop](https://user-images.githubusercontent.com/5817670/57789541-6f8f1500-7739-11e9-9a52-40d49577d710.png)

ideally there is a single development branch for plotting beachballs, and I'm not sure the best way forward, but maybe through this pyrocko compatibility package?
https://pyrocko.org/docs/current/library/examples/obspy_compat.html

Resolving patch:
diff --git a/obspy/imaging/beachball.py b/obspy/imaging/beachball.py
--- a/obspy/imaging/beachball.py
+++ b/obspy/imaging/beachball.py
@@ -146,7 +146,7 @@ def beach(fm, linewidth=2, facecolor='b', bgcolor='w', edgecolor='k',
     # Return as collection
     plot_dc_used = True
     if mt:
-        (t, n, p) = mt2axes(mt)
+        (t, n, p) = mt2axes(mt.normalized)
         if np.fabs(n.val) < EPSILON and np.fabs(t.val + p.val) < EPSILON:
             colors, p = plot_dc(np1, size, xy=xy, width=width)
         else:
@@ -1016,6 +1016,14 @@ def __init__(self, *args):
         else:
             raise TypeError("Wrong size of input parameter.")
 
+    @property
+    def normalized(self):
+        return MomentTensor(self.mt_normalized, self.expo)
+
+    @property
+    def mt_normalized(self):
+        return self.mt / np.linalg.norm(self.mt)
+
     @property
     def xx(self):
         return self.mt[0][0]


Test patch: