简体   繁体   English

MatPlotLib - 子图的子图或单个图上的多个断轴图

[英]MatPlotLib - Subplots of subplot or multiple broken axis charts on single plot

Wondering if its possible to create subplots of a subplot.想知道是否可以创建子图的子图。 The reason I am looking to do this is to create 3 broken axis charts on a single plot.我希望这样做的原因是在一个图上创建 3 个断轴图。 I understand how to create a single broken axis chart with the example code below, but since a broken axis chart requires the use of subplots I am now in a position where I am trying to use subplots to create 3 columns, then subplot those columns into a subplot with 2 rows to create the broken axis chart.我了解如何使用下面的示例代码创建单个断轴图,但是由于断轴图需要使用子图,我现在处于尝试使用子图创建 3 列的位置,然后将这些列子图到一个有 2 行的子图来创建断轴图。 See below for visual explanation.请参阅下面的视觉解释。

"""
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()

Desired Output 3 subplots, each containing 2 subplots期望输出3 个子图,每个子图包含 2 个子图

3 个子图,每个子图包含 2 个子图

First of all you cannot create a subplot of a subplot.首先,您不能创建子图的子图。 Subplots are axes objects placed in a figure and an axes cannot have "child axes".子图是放置在图形中的axes对象,轴不能有“子轴”。

The solution to your problem would be to create 6 subplots and apply sharex=True to the respective axes.您的问题的解决方案是创建 6 sharex=True图并将sharex=True应用于相应的轴。

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()

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM