[Your-Name-Here] - Fab Futures - Data Science
Home About

The Earth is quaking 🌍¢

The planet goes jiggle-jiggle πŸͺΌπŸ’ƒπŸ•ΊΒΆ

Let's import some data hereΒΆ

No description has been provided for this image

Let's start by getting our hands on a dataset! We have downloaded a 7-day .csv dataset from the USGS website, filtered for earthquakes with a magnitude stronger than 5, and and put it under:ΒΆ

'datasets/earthquakes.csv'

We shall read the .csv with pandas and print it to verify it is parsed correctly.ΒΆ

InΒ [143]:
import pandas as pd

# Load the earthquake data
data = pd.read_csv('datasets/earthquakes.csv')

# Print to check
print(data)
                        time  latitude  longitude    depth  mag magType  nst  \
0   2025-11-24T02:21:02.756Z    7.4819   -37.0268   10.000  5.4     mww   82   
1   2025-11-23T08:21:46.286Z   51.4112  -177.0684   54.820  5.5     mww  109   
2   2025-11-23T04:39:22.232Z   13.3402    95.8348   10.000  5.3     mww   48   
3   2025-11-23T03:19:55.726Z    1.2749   128.5695   10.000  5.4     mww   61   
4   2025-11-22T18:41:19.405Z    8.7615   -84.1029    8.031  5.1     mww  158   
5   2025-11-21T22:38:09.124Z   49.6155   158.6388   10.000  5.7     mww   95   
6   2025-11-21T12:37:59.558Z  -24.2360   179.9218  519.151  5.6     mww  111   
7   2025-11-21T12:22:03.648Z   39.6282   143.5446   10.000  5.5     mww   98   
8   2025-11-21T04:38:26.465Z   23.8942    90.5788   10.000  5.5     mww  101   
9   2025-11-20T23:36:07.248Z   25.6353   124.8355  120.250  5.1     mww   91   
10  2025-11-20T15:55:45.358Z  -11.5975   164.5887   44.810  5.0      mb   28   
11  2025-11-20T12:50:02.013Z  -25.3510  -176.5576   96.408  5.4     mww   70   
12  2025-11-20T06:59:44.153Z   -3.7031   128.3705  128.344  5.8     mww   84   
13  2025-11-20T04:19:54.753Z    1.5789   127.1375  136.935  5.4      mb   52   
14  2025-11-20T01:06:49.304Z  -31.5946  -178.7643  114.275  5.1      mb   33   
15  2025-11-19T21:45:22.218Z  -57.9631   -25.1924   39.527  5.0      mb   43   
16  2025-11-19T06:39:01.963Z  -37.8809   -75.1065   10.000  5.0     mww   50   
17  2025-11-19T02:23:19.189Z   39.2352   143.4678   10.000  5.0      mb   38   
18  2025-11-19T01:38:53.994Z   10.8709   -62.7566  122.975  5.0     mww   65   
19  2025-11-18T22:36:32.878Z    8.7898   -84.0158   10.000  5.4     mww   82   
20  2025-11-18T15:35:29.949Z  -11.9799    65.7397   10.000  5.3     mww  240   
21  2025-11-17T19:06:35.519Z   39.7568   143.1957   33.331  5.2     mww   98   
22  2025-11-17T17:23:03.682Z   12.1277   -86.4514  128.024  5.3     mww   66   
23  2025-11-17T12:12:37.800Z    0.1060   124.0046  119.483  5.3     mww  116   
24  2025-11-17T09:48:31.919Z  -61.1895   159.6597   10.000  5.0      mb   16   
25  2025-11-17T00:46:17.538Z  -11.0885  -106.3645   10.000  5.0      mb   72   

    gap    dmin   rms  ...                   updated  \
0    51  13.268  1.53  ...  2025-11-24T04:43:00.104Z   
1    92   0.366  0.92  ...  2025-11-24T08:47:46.499Z   
2    93   3.517  1.15  ...  2025-11-24T13:12:55.040Z   
3    84   3.427  1.26  ...  2025-11-24T03:45:38.429Z   
4   136   0.978  0.84  ...  2025-11-22T23:02:19.040Z   
5    74   3.547  0.96  ...  2025-11-22T23:01:23.571Z   
6    22   6.690  0.91  ...  2025-11-22T13:03:52.062Z   
7    99   2.225  0.72  ...  2025-11-22T12:50:13.363Z   
8    49   4.820  0.89  ...  2025-11-24T18:31:48.787Z   
9    37   1.364  0.68  ...  2025-11-21T21:49:35.040Z   
10  111   5.043  0.78  ...  2025-11-20T16:12:37.040Z   
11  126   8.757  1.17  ...  2025-11-21T13:31:14.724Z   
12   42   1.733  0.93  ...  2025-11-21T09:06:50.940Z   
13   79   3.544  0.83  ...  2025-11-21T04:40:10.118Z   
14   93   6.424  0.79  ...  2025-11-20T01:25:28.040Z   
15   69   7.309  0.68  ...  2025-11-19T22:05:04.040Z   
16  154   2.388  1.16  ...  2025-11-19T16:55:17.821Z   
17  138   2.411  1.06  ...  2025-11-19T21:39:47.136Z   
18   92   4.144  1.20  ...  2025-11-19T02:13:52.916Z   
19   84   0.946  0.76  ...  2025-11-20T02:24:04.357Z   
20   31   8.023  0.54  ...  2025-11-19T23:00:55.040Z   
21   85   1.929  0.55  ...  2025-11-18T19:35:38.249Z   
22  126   0.793  1.18  ...  2025-11-18T13:48:50.776Z   
23   25   3.374  1.02  ...  2025-11-17T12:31:48.040Z   
24  142   6.721  0.47  ...  2025-11-17T10:13:34.040Z   
25   86  16.197  0.56  ...  2025-11-17T02:48:46.040Z   

                                     place        type horizontalError  \
0               central Mid-Atlantic Ridge  earthquake           10.61   
1                59 km SSW of Adak, Alaska  earthquake            4.40   
2     267 km WSW of Dawei, Burma (Myanmar)  earthquake            9.93   
3             70 km NNE of Maba, Indonesia  earthquake            7.27   
4   67 km WSW of Puerto CortΓ©s, Costa Rica  earthquake            7.62   
5     214 km SE of Severo-Kuril’sk, Russia  earthquake            8.31   
6                south of the Fiji Islands  earthquake           11.76   
7                137 km E of Miyako, Japan  earthquake            3.25   
8       14 km WSW of Narsingdi, Bangladesh  earthquake            8.62   
9              103 km NNW of Hirara, Japan  earthquake            7.05   
10      163 km SW of Lata, Solomon Islands  earthquake           11.62   
11               south of the Fiji Islands  earthquake           10.53   
12             20 km E of Ambon, Indonesia  earthquake            7.63   
13         91 km NNW of Ternate, Indonesia  earthquake            8.16   
14                 Kermadec Islands region  earthquake           12.84   
15           South Sandwich Islands region  earthquake           11.36   
16               131 km WSW of Lebu, Chile  earthquake            4.44   
17             133 km ESE of Yamada, Japan  earthquake            8.85   
18     34 km NNE of Yaguaraparo, Venezuela  earthquake           11.10   
19  57 km WSW of Puerto CortΓ©s, Costa Rica  earthquake            5.34   
20                        Mid-Indian Ridge  earthquake            2.83   
21               108 km E of Miyako, Japan  earthquake            7.19   
22  12 km WSW of Ciudad Sandino, Nicaragua  earthquake            7.91   
23           61 km SW of Modisi, Indonesia  earthquake            7.12   
24                  Balleny Islands region  earthquake           13.36   
25               central East Pacific Rise  earthquake           13.58   

   depthError  magError  magNst    status  locationSource magSource  
0       1.871     0.098      10  reviewed              us        us  
1       5.555     0.053      34  reviewed              us        us  
2       1.888     0.083      14  reviewed              us        us  
3       1.874     0.103       9  reviewed              us        us  
4       4.734     0.048      41  reviewed              us        us  
5       1.840     0.093      11  reviewed              us        us  
6       5.489     0.071      19  reviewed              us        us  
7       1.842     0.065      23  reviewed              us        us  
8       1.837     0.098      10  reviewed              us        us  
9       5.671     0.065      23  reviewed              us        us  
10      7.857     0.078      53  reviewed              us        us  
11      5.150     0.069      20  reviewed              us        us  
12      6.586     0.048      41  reviewed              us        us  
13      7.646     0.067      75  reviewed              us        us  
14      7.928     0.108      28  reviewed              us        us  
15      6.488     0.080      50  reviewed              us        us  
16      1.881     0.052      35  reviewed              us        us  
17      1.905     0.086      43  reviewed              us        us  
18      6.011     0.056      31  reviewed              us        us  
19      1.727     0.050      39  reviewed              us        us  
20      1.723     0.073      18  reviewed              us        us  
21      4.886     0.073      18  reviewed              us        us  
22      5.336     0.056      31  reviewed              us        us  
23      6.309     0.062      25  reviewed              us        us  
24      1.958     0.146      15  reviewed              us        us  
25      1.844     0.036     242  reviewed              us        us  

[26 rows x 22 columns]

Ok, this looks cute, there is actually data in here :) We can also output the columns of the data for our reference, to know what information is available in the dataset.ΒΆ

InΒ [33]:
data.columns
Out[33]:
Index(['time', 'latitude', 'longitude', 'depth', 'mag', 'magType', 'nst',
       'gap', 'dmin', 'rms', 'net', 'id', 'updated', 'place', 'type',
       'horizontalError', 'depthError', 'magError', 'magNst', 'status',
       'locationSource', 'magSource'],
      dtype='object')

VisualizationΒΆ

Let's first plot a simple 1D graph.ΒΆ

I have no idea how to use pandas to plot, so let's start with something super simple. The data is a time series of earthquakes, so maybe plot the magnitudes of the earthquakes over time? We could use the 'time' column and the 'mag' column.ΒΆ

I'm not sure how the code will look like in the end, but it must be something of the form:ΒΆ

plot(x, y)

or better say:ΒΆ

plot(time, mag)

Let's try to create the variables for time and data_values first, we'll figure out the plotting shenanigans later. Seems like pandas allows to reference the column directly by its name and not an index, which is actually quite easy.ΒΆ

InΒ [34]:
data['time']
Out[34]:
0     2025-11-24T02:21:02.756Z
1     2025-11-23T08:21:46.286Z
2     2025-11-23T04:39:22.232Z
3     2025-11-23T03:19:55.726Z
4     2025-11-22T18:41:19.405Z
5     2025-11-21T22:38:09.124Z
6     2025-11-21T12:37:59.558Z
7     2025-11-21T12:22:03.648Z
8     2025-11-21T04:38:26.465Z
9     2025-11-20T23:36:07.248Z
10    2025-11-20T15:55:45.358Z
11    2025-11-20T12:50:02.013Z
12    2025-11-20T06:59:44.153Z
13    2025-11-20T04:19:54.753Z
14    2025-11-20T01:06:49.304Z
15    2025-11-19T21:45:22.218Z
16    2025-11-19T06:39:01.963Z
17    2025-11-19T02:23:19.189Z
18    2025-11-19T01:38:53.994Z
19    2025-11-18T22:36:32.878Z
20    2025-11-18T15:35:29.949Z
21    2025-11-17T19:06:35.519Z
22    2025-11-17T17:23:03.682Z
23    2025-11-17T12:12:37.800Z
24    2025-11-17T09:48:31.919Z
25    2025-11-17T00:46:17.538Z
Name: time, dtype: object

Boom! There you go. Ok, so the format I'm seeing here has numbers and letters, which tells me it is a string. Let's check it.ΒΆ

InΒ [35]:
type(data['time'])
Out[35]:
pandas.core.series.Series

Ah, great, I'm stupid. Of course, the type of a pandas series is a... pandas series...ΒΆ

Ok, how do I check the type of what's inside the series? Like, I want to apply the type() function to the content of the series, not the whole actual series...ΒΆ

Aha, according to the pandas reference, you can use the apply method, and pass whatever function you want to use... Let's see if this works...ΒΆ

InΒ [36]:
data['time'].apply(type)
Out[36]:
0     <class 'str'>
1     <class 'str'>
2     <class 'str'>
3     <class 'str'>
4     <class 'str'>
5     <class 'str'>
6     <class 'str'>
7     <class 'str'>
8     <class 'str'>
9     <class 'str'>
10    <class 'str'>
11    <class 'str'>
12    <class 'str'>
13    <class 'str'>
14    <class 'str'>
15    <class 'str'>
16    <class 'str'>
17    <class 'str'>
18    <class 'str'>
19    <class 'str'>
20    <class 'str'>
21    <class 'str'>
22    <class 'str'>
23    <class 'str'>
24    <class 'str'>
25    <class 'str'>
Name: time, dtype: object

Alright! So these are actually strings... Well, string is not a good variable to work with, at least not for time series. Let's convert it to something more useful - one would usually use the datetime type. We'll conver the time columnt using the to_datetime() method. We probably should be able to write the converted column to the table, using the same "indexing" with the square brackets and column name. Let's call the new column cute_datetime.ΒΆ

InΒ [45]:
data['cute_datetime'] = pd.to_datetime(data['time'])
data
Out[45]:
time latitude longitude depth mag magType nst gap dmin rms ... place type horizontalError depthError magError magNst status locationSource magSource cute_datetime
0 2025-11-24T02:21:02.756Z 7.4819 -37.0268 10.000 5.4 mww 82 51 13.268 1.53 ... central Mid-Atlantic Ridge earthquake 10.61 1.871 0.098 10 reviewed us us 2025-11-24 02:21:02.756000+00:00
1 2025-11-23T08:21:46.286Z 51.4112 -177.0684 54.820 5.5 mww 109 92 0.366 0.92 ... 59 km SSW of Adak, Alaska earthquake 4.40 5.555 0.053 34 reviewed us us 2025-11-23 08:21:46.286000+00:00
2 2025-11-23T04:39:22.232Z 13.3402 95.8348 10.000 5.3 mww 48 93 3.517 1.15 ... 267 km WSW of Dawei, Burma (Myanmar) earthquake 9.93 1.888 0.083 14 reviewed us us 2025-11-23 04:39:22.232000+00:00
3 2025-11-23T03:19:55.726Z 1.2749 128.5695 10.000 5.4 mww 61 84 3.427 1.26 ... 70 km NNE of Maba, Indonesia earthquake 7.27 1.874 0.103 9 reviewed us us 2025-11-23 03:19:55.726000+00:00
4 2025-11-22T18:41:19.405Z 8.7615 -84.1029 8.031 5.1 mww 158 136 0.978 0.84 ... 67 km WSW of Puerto CortΓ©s, Costa Rica earthquake 7.62 4.734 0.048 41 reviewed us us 2025-11-22 18:41:19.405000+00:00
5 2025-11-21T22:38:09.124Z 49.6155 158.6388 10.000 5.7 mww 95 74 3.547 0.96 ... 214 km SE of Severo-Kuril’sk, Russia earthquake 8.31 1.840 0.093 11 reviewed us us 2025-11-21 22:38:09.124000+00:00
6 2025-11-21T12:37:59.558Z -24.2360 179.9218 519.151 5.6 mww 111 22 6.690 0.91 ... south of the Fiji Islands earthquake 11.76 5.489 0.071 19 reviewed us us 2025-11-21 12:37:59.558000+00:00
7 2025-11-21T12:22:03.648Z 39.6282 143.5446 10.000 5.5 mww 98 99 2.225 0.72 ... 137 km E of Miyako, Japan earthquake 3.25 1.842 0.065 23 reviewed us us 2025-11-21 12:22:03.648000+00:00
8 2025-11-21T04:38:26.465Z 23.8942 90.5788 10.000 5.5 mww 101 49 4.820 0.89 ... 14 km WSW of Narsingdi, Bangladesh earthquake 8.62 1.837 0.098 10 reviewed us us 2025-11-21 04:38:26.465000+00:00
9 2025-11-20T23:36:07.248Z 25.6353 124.8355 120.250 5.1 mww 91 37 1.364 0.68 ... 103 km NNW of Hirara, Japan earthquake 7.05 5.671 0.065 23 reviewed us us 2025-11-20 23:36:07.248000+00:00
10 2025-11-20T15:55:45.358Z -11.5975 164.5887 44.810 5.0 mb 28 111 5.043 0.78 ... 163 km SW of Lata, Solomon Islands earthquake 11.62 7.857 0.078 53 reviewed us us 2025-11-20 15:55:45.358000+00:00
11 2025-11-20T12:50:02.013Z -25.3510 -176.5576 96.408 5.4 mww 70 126 8.757 1.17 ... south of the Fiji Islands earthquake 10.53 5.150 0.069 20 reviewed us us 2025-11-20 12:50:02.013000+00:00
12 2025-11-20T06:59:44.153Z -3.7031 128.3705 128.344 5.8 mww 84 42 1.733 0.93 ... 20 km E of Ambon, Indonesia earthquake 7.63 6.586 0.048 41 reviewed us us 2025-11-20 06:59:44.153000+00:00
13 2025-11-20T04:19:54.753Z 1.5789 127.1375 136.935 5.4 mb 52 79 3.544 0.83 ... 91 km NNW of Ternate, Indonesia earthquake 8.16 7.646 0.067 75 reviewed us us 2025-11-20 04:19:54.753000+00:00
14 2025-11-20T01:06:49.304Z -31.5946 -178.7643 114.275 5.1 mb 33 93 6.424 0.79 ... Kermadec Islands region earthquake 12.84 7.928 0.108 28 reviewed us us 2025-11-20 01:06:49.304000+00:00
15 2025-11-19T21:45:22.218Z -57.9631 -25.1924 39.527 5.0 mb 43 69 7.309 0.68 ... South Sandwich Islands region earthquake 11.36 6.488 0.080 50 reviewed us us 2025-11-19 21:45:22.218000+00:00
16 2025-11-19T06:39:01.963Z -37.8809 -75.1065 10.000 5.0 mww 50 154 2.388 1.16 ... 131 km WSW of Lebu, Chile earthquake 4.44 1.881 0.052 35 reviewed us us 2025-11-19 06:39:01.963000+00:00
17 2025-11-19T02:23:19.189Z 39.2352 143.4678 10.000 5.0 mb 38 138 2.411 1.06 ... 133 km ESE of Yamada, Japan earthquake 8.85 1.905 0.086 43 reviewed us us 2025-11-19 02:23:19.189000+00:00
18 2025-11-19T01:38:53.994Z 10.8709 -62.7566 122.975 5.0 mww 65 92 4.144 1.20 ... 34 km NNE of Yaguaraparo, Venezuela earthquake 11.10 6.011 0.056 31 reviewed us us 2025-11-19 01:38:53.994000+00:00
19 2025-11-18T22:36:32.878Z 8.7898 -84.0158 10.000 5.4 mww 82 84 0.946 0.76 ... 57 km WSW of Puerto CortΓ©s, Costa Rica earthquake 5.34 1.727 0.050 39 reviewed us us 2025-11-18 22:36:32.878000+00:00
20 2025-11-18T15:35:29.949Z -11.9799 65.7397 10.000 5.3 mww 240 31 8.023 0.54 ... Mid-Indian Ridge earthquake 2.83 1.723 0.073 18 reviewed us us 2025-11-18 15:35:29.949000+00:00
21 2025-11-17T19:06:35.519Z 39.7568 143.1957 33.331 5.2 mww 98 85 1.929 0.55 ... 108 km E of Miyako, Japan earthquake 7.19 4.886 0.073 18 reviewed us us 2025-11-17 19:06:35.519000+00:00
22 2025-11-17T17:23:03.682Z 12.1277 -86.4514 128.024 5.3 mww 66 126 0.793 1.18 ... 12 km WSW of Ciudad Sandino, Nicaragua earthquake 7.91 5.336 0.056 31 reviewed us us 2025-11-17 17:23:03.682000+00:00
23 2025-11-17T12:12:37.800Z 0.1060 124.0046 119.483 5.3 mww 116 25 3.374 1.02 ... 61 km SW of Modisi, Indonesia earthquake 7.12 6.309 0.062 25 reviewed us us 2025-11-17 12:12:37.800000+00:00
24 2025-11-17T09:48:31.919Z -61.1895 159.6597 10.000 5.0 mb 16 142 6.721 0.47 ... Balleny Islands region earthquake 13.36 1.958 0.146 15 reviewed us us 2025-11-17 09:48:31.919000+00:00
25 2025-11-17T00:46:17.538Z -11.0885 -106.3645 10.000 5.0 mb 72 86 16.197 0.56 ... central East Pacific Rise earthquake 13.58 1.844 0.036 242 reviewed us us 2025-11-17 00:46:17.538000+00:00

26 rows Γ— 23 columns

Okay! This works. These look more like timestamps, with date and time. Also, I just accidentally discovered that if you don't useΒΆ

print(data)

But actually run justΒΆ

data

Then Jupyter shows you a much more user-friendly version of the table. If we scroll to the very right we see our newly added column there.ΒΆ

Also, can I use square brackets to index a single value from the series?ΒΆ

InΒ [38]:
data['datetime'][1]
Out[38]:
Timestamp('2025-11-23 08:21:46.286000+0000', tz='UTC')

Beautiful! Ok, let's look at the magnitudes.ΒΆ

InΒ [39]:
data['mag'][:5]
Out[39]:
0    5.4
1    5.5
2    5.3
3    5.4
4    5.1
Name: mag, dtype: float64

Nice! We can slice the indices just like we have learned before. Also, these are floats, as the type says. I think we can try to plot this now.ΒΆ

InΒ [52]:
import matplotlib.pyplot as plt

plt.figure()
plt.plot(data['cute_datetime'], data['mag'])
plt.show()
No description has been provided for this image

Alrighty! Looks like the data we wanted to see - earthquakes stronger than 5, as they happened over the last 7 days.ΒΆ

The data does make sense, but the plot looks ugly, let's look at the reference of matplotlib to see how we can make it nicer. Let's try adding labels to the x- and y- axis, and a title to the overall plot.ΒΆ

InΒ [87]:
import matplotlib.pyplot as plt

plt.figure()
plt.plot(data['cute_datetime'], data['mag'])

plt.xlabel('Time')                                      # Add x-label
plt.ylabel('Magnitude')                                 # Add y-label
plt.title('Earthquake magnitudes over the last 7 days') # Add title

plt.show()
No description has been provided for this image

Yep, better now. But that ticks on the time axis are still horrible, they all overlap. Can we rotate them?ΒΆ

InΒ [89]:
import matplotlib.pyplot as plt

plt.figure()
plt.plot(data['cute_datetime'], data['mag'])

plt.xlabel('Time')
plt.ylabel('Magnitude')
plt.title('Earthquake magnitudes over the last 7 days')

plt.xticks(rotation=45) # los rotaΓ§iones

plt.show()
No description has been provided for this image

Ok, much better now! One last touch - need a better color here.ΒΆ

InΒ [58]:
import matplotlib.pyplot as plt

plt.figure()
plt.plot(data['cute_datetime'], data['mag'], color='m') # mmmmmmmagenta!

plt.xlabel('Time')
plt.ylabel('Magnitude')
plt.title('Earthquake magnitudes over the last 7 days')

plt.xticks(rotation=45)

plt.show()
No description has been provided for this image

Boom! There you have it. M for magenta. I'm happy with this so far. Now let's attempt.. SOMETHING BIGGER 😈 muaahahaha¢

LET THE MAPPING BEGIN! πŸ—ΊοΈΒΆ

Since this is geo-data, and the table has not just magnitudes, but also GPS-coordinates the earthquakes, it would make sense to show them on the map!ΒΆ

I've asked GPT and it says you should use folium for this type of fun, so let's install it first.ΒΆ

InΒ [60]:
pip install folium
Requirement already satisfied: folium in /opt/conda/lib/python3.13/site-packages (0.20.0)
Requirement already satisfied: branca>=0.6.0 in /opt/conda/lib/python3.13/site-packages (from folium) (0.8.2)
Requirement already satisfied: jinja2>=2.9 in /opt/conda/lib/python3.13/site-packages (from folium) (3.1.6)
Requirement already satisfied: numpy in /opt/conda/lib/python3.13/site-packages (from folium) (2.3.3)
Requirement already satisfied: requests in /opt/conda/lib/python3.13/site-packages (from folium) (2.32.5)
Requirement already satisfied: xyzservices in /opt/conda/lib/python3.13/site-packages (from folium) (2025.4.0)
Requirement already satisfied: MarkupSafe>=2.0 in /opt/conda/lib/python3.13/site-packages (from jinja2>=2.9->folium) (3.0.3)
Requirement already satisfied: charset_normalizer<4,>=2 in /opt/conda/lib/python3.13/site-packages (from requests->folium) (3.4.4)
Requirement already satisfied: idna<4,>=2.5 in /opt/conda/lib/python3.13/site-packages (from requests->folium) (3.11)
Requirement already satisfied: urllib3<3,>=1.21.1 in /opt/conda/lib/python3.13/site-packages (from requests->folium) (2.5.0)
Requirement already satisfied: certifi>=2017.4.17 in /opt/conda/lib/python3.13/site-packages (from requests->folium) (2025.10.5)
Note: you may need to restart the kernel to use updated packages.

Okie-dokie. Whenever making something difficult, we always build up from something simple, adding complexity step-by-step. Otherwise if we write a ton of code and it doesn't work in the end - we have no idea why. So let's start by displaying an empty map.ΒΆ

InΒ [64]:
import folium

cute_map = folium.Map()                          # Create an empty map
cute_map.save('earthquakes_cute_basic_map.html') # Save it
cute_map                                         # Show it
Out[64]:
Make this Notebook Trusted to load map: File -> Trust Notebook

Aha, mhm! Let's understand how to add markers here.ΒΆ

It seems that we can use the .CircleMarker() method to create a marker cluster with our required properties (location, radius, etc.) and add it to the map using the .add_to() method:ΒΆ

folium.CircleMarker(*some properties).add_to(cute_map)

Let's try adding one marker first.ΒΆ

InΒ [86]:
import folium

cute_map = folium.Map()

folium.CircleMarker(location = [0, 0], radius = 5).add_to(cute_map) # Adding a marker at location 0,0, with radius 5

cute_map.save('earthquakes_cute_basic_map.html')
cute_map
Out[86]:
Make this Notebook Trusted to load map: File -> Trust Notebook

Would you look at that! A cute little circle. How about we iterate through the whole table and repeat this command and get a bunch of actual markers! We can replace the [0, 0] in the location property with entries from the table, but then the code gets a bit cluttered. Instead, let's create variables right before that and put variables into the CircleMarker to keep the code clean. Pure aesthetics, but aesthetics nevertheless 🀌¢

InΒ [84]:
import folium

cute_map = folium.Map()

for i in range(len(data)):
    lat = data['latitude'][i]
    lon = data['longitude'][i]
    folium.CircleMarker(location = [lat, lon], radius = 5).add_to(cute_map)

cute_map.save('earthquakes_cute_basic_map.html')
cute_map
Out[84]:
Make this Notebook Trusted to load map: File -> Trust Notebook

Cuteness! Now let's get creative. How about we scale the radius with the magnitude? Also I want the circles to be filled.ΒΆ

InΒ [180]:
import folium

cute_map = folium.Map()

for i in range(len(data)):
    lat = data['latitude'][i]
    lon = data['longitude'][i]
    mag = 10*(data['mag'][i]-4) # 10* and -4 looks like random voodoo magic, because it is.
    folium.CircleMarker(location = [lat, lon],
                        radius = mag,
                        fill = True
                       ).add_to(cute_map)

cute_map.save('earthquakes_cute_basic_map.html')
cute_map
Out[180]:
Make this Notebook Trusted to load map: File -> Trust Notebook

Speaking of aesthetics... Let's remove the circles and only leave the insides for a flatter look, and adjust the opacity a bit... We can also use an if-statement to change the color based on how strong the earthquake was - this sould make the visualization much more telling πŸ‘€ΒΆ

InΒ [184]:
import folium

cute_map = folium.Map()

for i in range(len(data)):
    lat = data['latitude'][i]
    lon = data['longitude'][i]
    mag = 10*(data['mag'][i]-4)

    # Conditional structure to change the color based on magnitude
    if data['mag'][i] < 5.3:
        color = 'green'
    elif data['mag'][i] < 5.6:
        color = 'yellow'
    else:
        color = 'red'
        
    folium.CircleMarker(location = [lat, lon],
                        radius = mag,
                        fill = True,
                        color = None,
                        fill_color = color,
                        fill_opacity = 0.4
                       ).add_to(cute_map)

cute_map.save('earthquakes_cute_basic_map.html')
cute_map
Out[184]:
Make this Notebook Trusted to load map: File -> Trust Notebook

Oooha, this starts to look like something now! How about we import the data with no filters (we filtered above magnitude 5 before, let's get the full data with all earthquakes now). Also, let's do some GPT magic to give us a continuous color map based on magnitude, instead of 3 discrete colors we used in the if-statement.ΒΆ

InΒ [185]:
import folium
import matplotlib.colors as mcolors

data_full = pd.read_csv('datasets/earthquakes_no_filter.csv')

# GPT magic for a continuous colormap from green to yellow to red - no idea what's happening here.
cmap = mcolors.LinearSegmentedColormap.from_list("green_yellow_red", ['green', 'yellow', 'red'])
norm = mcolors.Normalize(vmin=0, vmax=8)

cute_map = folium.Map()

for i in range(len(data_full)):
    lat = data_full['latitude'][i]
    lon = data_full['longitude'][i]
    mag = data_full['mag'][i]
    color = mcolors.to_hex(cmap(norm(mag))) # Continuation of the color magic
        
    folium.CircleMarker(location = [lat, lon],
                        radius = 3*mag,
                        fill = True,
                        color = None,
                        fill_color = color,
                        fill_opacity = 0.8
                       ).add_to(cute_map)

cute_map.save('earthquakes_cute_basic_map.html')
cute_map
Out[185]:
Make this Notebook Trusted to load map: File -> Trust Notebook

Iiiiinteresting...! What do we see here. πŸ‘€ Alaska does a lot of cute little jiggly-jiggles - same with US West Coast. Meanwhile Asia and South America don't do many moves, but when they finally do - it's a whole boogie. Is it always like this? πŸ€” Or just the last 7 days? πŸ€” Could we look at more historical data and compare the frequency and magnitude of the events in different regions - we could know for sure... oh man... if only there was a data science course where I could learn all this..ΒΆ

Oh wait!...ΒΆ