Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating subplots with equal axis scale, Python, matplotlib

I am plotting seismological data and am creating a figure featuring 16 subplots of different depth slices. Each subplot displays the lat/lon of the epicenter and the color is scaled to its magnitude. I am trying to do two things:

  1. Adjust the scale of all plots to equal the x and y min and max for the area selected. This will allow easy comparison across the plots. (so all plots would range from xmin to xmax etc)

  2. adjust the magnitude colors so they also represent the scale (ie colors represent all available points not just the points on that specific sub plot)

I have seen this accomplished a number of ways but am struggling to apply them to the loop in my code. The data I am using is here: Data.

I posted my code and what the current output looks like below.

import matplotlib.pyplot as plt
import pandas as pd

eq_df = pd.read_csv(eq_csv)
eq_data = eq_df[['LON', 'LAT', 'DEPTH', 'MAG']]
nbound = max(eq_data.LAT)
sbound = min(eq_data.LAT)
ebound = max(eq_data.LON)
wbound = min(eq_data.LON)

xlimit = (wbound, ebound)
ylimit = (sbound, nbound)

magmin = min(eq_data.MAG)
magmax = max(eq_data.MAG)

for n in list(range(1,17)):
    km = eq_data[(eq_data.DEPTH > n - 1) & (eq_data.DEPTH <= n)]
    plt.subplot(4, 4, n)
    plt.scatter(km["LON"], km['LAT'], s = 10, c = km['MAG'], vmin = magmin, vmax = magmax) #added vmin/vmax to scale my magnitude data
    plt.ylim(sbound, nbound) # set y limits of plot
    plt.xlim(wbound, ebound) # set x limits of plot
    plt.tick_params(axis='both', which='major', labelsize= 6)
    plt.subplots_adjust(hspace = 1)
    plt.gca().set_title('Depth = ' + str(n - 1) +'km to ' + str(n) + 'km', size = 8) #set title of subplots
    plt.suptitle('Magnitude of Events at Different Depth Slices, 1950 to Today')
plt.show()

Current Figure

ETA: new code to resolve my issue

like image 693
Richard Avatar asked Jan 22 '20 20:01

Richard


People also ask

How do I display multiple images in one figure correctly in matplotlib?

MatPlotLib with PythonCreate random data using numpy. Add a subplot to the current figure, nrows=1, ncols=4 and at index=1. Display data as an image, i.e., on a 2D regular raster, using imshow() method with cmap="Blues_r". Add a subplot to the current figure, nrows=1, ncols=4 and at index=2.

How can you plot subplots with different sizes?

Create Different Subplot Sizes in Matplotlib using Gridspec The GridSpec from the gridspec module is used to adjust the geometry of the Subplot grid. We can use different parameters to adjust the shape, size, and number of columns and rows.


1 Answers

In response to this comment on the other answer, here is a demonstration of the use of sharex=True and sharey=True for this use case:

import matplotlib.pyplot as plt
import numpy as np

# Supply the limits since random data will be plotted
wbound = -0.1
ebound = 1.1
sbound = -0.1
nbound = 1.1

fig, axs = plt.subplots(nrows=4, ncols=4, figsize=(16,12), sharex=True, sharey=True)
plt.xlim(wbound, ebound)
plt.ylim(sbound, nbound)
for n, ax in enumerate(axs.flatten()):
    ax.scatter(np.random.random(20), np.random.random(20), 
               c = np.random.random(20), marker = '.')
    ticks = [n % 4 == 0, n > 12]
    ax.tick_params(left=ticks[0], bottom=ticks[1])
    ax.set_title('Depth = ' + str(n - 1) +'km to ' + str(n) + 'km', size = 12)

plt.suptitle('Magnitude of Events at Different Depth Slices, 1950 to Today', y = 0.95)
plt.subplots_adjust(wspace=0.05)
plt.show()

enter image description here

Explanation of a couple things:

  1. I have reduced the horizontal spacing between subplots with subplots_adjust(wspace=0.05)
  2. plt.suptitle does not need to be (and should not be) in the loop.
  3. ticks = [n % 4 == 0, n > 12] creates a pair of bools for each axis which is then used to control which tick marks are drawn.
  4. Left and bottom tick marks are controlled for each axis with ax.tick_params(left=ticks[0], bottom=ticks[1])
  5. plt.xlim() and plt.ylim() need only be called once, before the loop
like image 197
William Miller Avatar answered Sep 30 '22 12:09

William Miller