MatPlotLib: subplots de subplot o múltiples gráficos de ejes rotos en una sola plot

Preguntándose si es posible crear subplots de un subplot. La razón por la que busco hacer esto es crear 3 gráficos de ejes rotos en una sola gráfica. Entiendo cómo crear un solo gráfico de ejes rotos con el código de ejemplo a continuación, pero como un gráfico de ejes rotos requiere el uso de subplots, ahora estoy en una posición en la que estoy tratando de usar subplots para crear 3 columnas, luego subplotear esas columnas en una ttwig secundaria con 2 filas para crear el gráfico de ejes rotos. Vea a continuación la explicación visual.

""" EXAMPLE OF A SINGLE BROKEN AXIS CHART """ import matplotlib.pyplot as plt import numpy as np # 30 points between 0 0.2] originally made using np.random.rand(30)*.2 ptsA = np.array([ 0.015, 0.166, 0.133, 0.159, 0.041, 0.024, 0.195, 0.039, 0.161, 0.018, 0.143, 0.056, 0.125, 0.096, 0.094, 0.051, 0.043, 0.021, 0.138, 0.075, 0.109, 0.195, 0.050, 0.074, 0.079, 0.155, 0.020, 0.010, 0.061, 0.008]) # Now let's make two outlier points which are far away from everything. ptsA[[3, 14]] += .8 # 30 points between 0 0.2] originally made using np.random.rand(30)*.2 ptsB = np.array([ 0.015, 0.166, 0.133, 0.159, 0.041, 0.024, 0.195, 0.039, 0.161, 0.018, 0.143, 0.056, 0.125, 0.096, 0.094, 0.051, 0.043, 0.021, 0.138, 0.075, 0.109, 0.195, 0.050, 0.074, 0.079, 0.155, 0.020, 0.010, 0.061, 0.008]) # Now let's make two outlier points which are far away from everything. ptsB[[1, 7, 9, 13, 15]] += .95 # If we were to simply plot pts, we'd lose most of the interesting # details due to the outliers. So let's 'break' or 'cut-out' the y-axis # into two portions - use the top (ax) for the outliers, and the bottom # (ax2) for the details of the majority of our data f, (ax, ax2) = plt.subplots(2, 1, sharex=True) # plot the same data on both axes ax.plot(ptsB) ax2.plot(pts) # zoom-in / limit the view to different portions of the data ax.set_ylim(.78, 1.) # outliers only ax2.set_ylim(0, .22) # most of the data # hide the spines between ax and ax2 ax.spines['bottom'].set_visible(False) ax2.spines['top'].set_visible(False) ax.xaxis.tick_top() ax.tick_params(labeltop='off') # don't put tick labels at the top ax2.xaxis.tick_bottom() # This looks pretty good, and was fairly painless, but you can get that # cut-out diagonal lines look with just a bit more work. The important # thing to know here is that in axes coordinates, which are always # between 0-1, spine endpoints are at these locations (0,0), (0,1), # (1,0), and (1,1). Thus, we just need to put the diagonals in the # appropriate corners of each of our axes, and so long as we use the # right transform and disable clipping. d = .015 # how big to make the diagonal lines in axes coordinates # arguments to pass plot, just so we don't keep repeating them kwargs = dict(transform=ax.transAxes, color='k', clip_on=False) ax.plot((-d, +d), (-d, +d), **kwargs) # top-left diagonal ax.plot((1 - d, 1 + d), (-d, +d), **kwargs) # top-right diagonal kwargs.update(transform=ax2.transAxes) # switch to the bottom axes ax2.plot((-d, +d), (1 - d, 1 + d), **kwargs) # bottom-left diagonal ax2.plot((1 - d, 1 + d), (1 - d, 1 + d), **kwargs) # bottom-right diagonal # What's cool about this is that now if we vary the distance between # ax and ax2 via f.subplots_adjust(hspace=...) or plt.subplot_tool(), # the diagonal lines will move accordingly, and stay right at the tips # of the spines they are 'breaking' plt.show() 

Salida deseada 3 subplots, cada una contiene 2 subplots

3 subparcelas, cada una con 2 subparcelas

En primer lugar, no puede crear una ttwig secundaria de una ttwig secundaria. Las subplots son objetos de axes colocados en una figura y los ejes no pueden tener “ejes secundarios”.

La solución a su problema sería crear 6 subplots y aplicar sharex=True a los ejes respectivos.

 import matplotlib.pyplot as plt import numpy as np data = np.random.rand(17, 6) data[15:, 3:] = np.random.rand(2, 3)+3. markers=["o", "p", "s"] colors=["r", "g", "b"] fig=plt.figure(figsize=(10, 4)) axes = [] for i in range(3): ax = fig.add_subplot(2,3,i+1) axes.append(ax) for i in range(3): ax = fig.add_subplot(2,3,i+4, sharex=axes[i]) axes.append(ax) for i in range(3): # plot same data in both top and down axes axes[i].plot(data[:,i], data[:,i+3], marker=markers[i], linestyle="", color=colors[i]) axes[i+3].plot(data[:,i], data[:,i+3], marker=markers[i], linestyle="", color=colors[i]) for i in range(3): axes[i].spines['bottom'].set_visible(False) axes[i+3].spines['top'].set_visible(False) axes[i].xaxis.tick_top() axes[i].tick_params(labeltop='off') # don't put tick labels at the top axes[i+3].xaxis.tick_bottom() axes[i].set_ylim([3,4]) axes[i+3].set_ylim([0,1]) axes[i].set_xlim([0,1]) #adjust space between subplots plt.subplots_adjust(hspace=0.08, wspace=0.4) plt.show() 

introduzca la descripción de la imagen aquí