Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Draw a line correlating zones between multiple subplots in matplotlib

I'm a geologist and have a bunch of boreholes of varying depth.

I've crudely set the number, width and height of the subplots to vary according to the number of boreholes and the number of samples in those boreholes.

In each borehole there is a zone i'd like to highlight, which I've done with axhspan.

What i'd like to do is correlate between the boreholes (the subplots), drawing a line connecting the top and bottom of all the zoned areas across all the boreholes.

I've tried using annotate but haven't progressed very far. I'm not really sure how to approach this and would appreciate any advice.

Here is some example code, and a pic of what it might produce

import numpy as np
import matplotlib.pyplot as plt
from random import randint

fig = plt.figure()

Wells=np.arange(0,10,1) #number of wells to plot

for i in Wells:
    samp=randint(50,100) #number of samples in well

    dist=0.02     #space between plots
    left=0.05     #left border
    right=0.05    #right border
    base=0.05     #bottom border
    width=((1.0-(left+right))/len(Wells))     #width of subplot
    height=(1.0-base)/(100.0/samp)            #height of subplot

    #create subplots
    ax = fig.add_axes([left+(i*width)+dist, 1.0-(base+height), width-dist, height])    #left,bottom,width,height of subplot

    #random data 
    x=np.random.random_integers(100,size=(samp))
    y=np.arange(0,len(x),1)

    #plot
    ax.plot(x,y,alpha=0.5)    

    #zone area of plot 
    zone=samp/2.5
    ax.axhspan(15, zone, color='k', alpha=0.2) #axis 'h' horizontal span

    #format
    ax.set_ylim(0,max(y))
    ax.set_xlim(0,max(x))
    ax.tick_params(axis='both',label1On=False,label2On=False)

plt.show()

enter image description here:

like image 634
user1665220 Avatar asked Oct 03 '22 16:10

user1665220


1 Answers

You can use matplotlib.patches.ConnectionPatch to make this connection.

Add before your for loop:

xys_bot = []
xys_top = []

And at the end of the for loop:

for i in Wells:
    #
    #...
    #
    xys_bot.append( ((x.max() - x.min())/2., 15) )
    xys_top.append( ((x.max() - x.min())/2., zone) )
    if i > 0:
        # bottom line
        p = ConnectionPatch(xyA = xys_bot[i-1], xyB = xys_bot[i],
               coordsA='data', coordsB='data',
               axesA=fig.axes[i-1], axesB=ax,
               arrowstyle='-')
        ax.add_artist(p)
        # top line
        p = ConnectionPatch(xyA = xys_top[i-1], xyB = xys_top[i],
               coordsA='data', coordsB='data',
               axesA=fig.axes[i-1], axesB=ax,
               arrowstyle='-')
        ax.add_artist(p)

plt.draw()
plt.show()
like image 157
Saullo G. P. Castro Avatar answered Oct 12 '22 12:10

Saullo G. P. Castro