1

I am trying to plot an ObsPy (or any python) seismic focal mechanism in time series.

import matplotlib.pyplot as plt
import datetime
import numpy as np
from obspy.imaging.beachball import Beach

# x = np.arange(0,100,4)
x = np.array([datetime.datetime(2013, 9, 28, i, 0) for i in range(24)])
y = np.random.randint(100, size=x.shape)

fig, ax = plt.subplots(figsize=(10,6))
ax.plot(x,y)

bball = Beach([70, 90, 80], xy=(x[10],y[10]), width=5, linewidth=1, alpha=0.85)

bball.set_zorder(1)
ax.add_collection(bball)
plt.show()

When using an integer/float series for x it works fine, but the time series fails here:

Traceback (most recent call last):
  File "./beachballs.py", line 15, in <module>
    bball = Beach([70, 90, 80], xy=(x[10],y[10]), width=5, linewidth=1, alpha=0.85)
  File "/usr/local/lib/python3.3/site-packages/obspy-0.9.2_787_gf176-py3.3-linux-x86_64.egg/obspy/imaging/beachball.py", line 119, in Beach
    colors, p = plotDC(np1, size=size, xy=xy, width=width)
  File "/usr/local/lib/python3.3/site-packages/obspy-0.9.2_787_gf176-py3.3-linux-x86_64.egg/obspy/imaging/beachball.py", line 645, in plotDC
    collect.append(xy2patch(Y, X, res, xy))
  File "/usr/local/lib/python3.3/site-packages/obspy-0.9.2_787_gf176-py3.3-linux-x86_64.egg/obspy/imaging/beachball.py", line 656, in xy2patch
    x = x * res[0] + xy[0]
TypeError: unsupported operand type(s) for +: 'float' and 'datetime.datetime'

The function xy2patch in the source code is trying to scale the time by a float value.

Any ideas? Hack the source? Other packages? Thanks.

mtrw
  • 34,200
  • 7
  • 63
  • 71
skytaker
  • 4,159
  • 1
  • 21
  • 31
  • I don't think many people will know about seismology packages (albeit it's interesting to learn about the plethora of stuff Python has to offer). Cannot you simply use `obspy` to get the data you want to plot, then plot it yourself so it doesn't have a chance to mess with `datetime`? Alternatively, have you tried using integers or floats as x axis unit and then changing the labels manually? – Aleksander Lidtke Jan 27 '15 at 17:41
  • Good suggestions. I will look at these options. – skytaker Jan 27 '15 at 19:34

1 Answers1

1

Found it. Convert times to matplotlib float representation.

import matplotlib.pyplot as plt
import datetime
import numpy as np
from obspy.imaging.beachball import Beach
from matplotlib.dates import date2num

# x = np.arange(0,100,4)

x = date2num(np.array([datetime.datetime(2013, 9, 28, i, 0) for i in range(24)]))
y = np.random.randint(100, size=x.shape)

fig, ax = plt.subplots(figsize=(10,6))
ax.plot(x,y)

bball = Beach([70, 90, 80], xy=(x[10],y[10]), width=(.1,15), linewidth=1, alpha=0.85)

bball.set_zorder(1)
ax.add_collection(bball)
plt.show()
miken32
  • 42,008
  • 16
  • 111
  • 154
skytaker
  • 4,159
  • 1
  • 21
  • 31