MatPlotLib - 子图的子图或单个图上的多个断轴图 [英] MatPlotLib - Subplots of subplot or multiple broken axis charts on single plot

查看:56
本文介绍了MatPlotLib - 子图的子图或单个图上的多个断轴图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

想知道是否可以创建子图的子图.我希望这样做的原因是在一个图上创建 3 个断轴图.我了解如何使用下面的示例代码创建单个断开的轴图,但是由于断开的轴图需要使用子图,因此我现在处于尝试使用子图创建3列的位置,然后将这些列子图绘制为一个有 2 行的子图来创建断轴图.有关视觉说明,请参见下文.

<代码>"""单轴残图示例"""导入matplotlib.pyplot作为plt将numpy导入为np#30介于0 0.2之间的点]最初是使用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])#现在让我们提出两个离所有事物都远的离群点.ptsA[[3, 14]] += .8# 0 0.2 之间的 30 点] 最初使用 np.random.rand(30)*.2ptsB = 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])# 现在让我们制作两个远离一切的离群点.ptsB[[1, 7, 9, 13, 15]] += .95# 如果我们只是简单地绘制 pts,我们会失去大部分有趣的东西# 由于异常值的细节.因此,让我们断开"或切除" y轴# 分成两部分 - 使用顶部(ax)作为异常值,底部使用# (ax2) 获取我们大部分数据的详细信息f, (ax, ax2) = plt.subplots(2, 1, sharex=True)#在两个轴上绘制相同的数据ax.plot(ptsB)ax2.plot(pts)# 放大/限制视图到数据的不同部分ax.set_ylim(.78, 1.) # 仅离群值ax2.set_ylim(0, .22) # 大部分数据# 隐藏 ax 和 ax2 之间的刺ax.spines ['bottom'].set_visible(False)ax2.spines['top'].set_visible(False)ax.xaxis.tick_top()ax.tick_params(labeltop='off') # 不要在顶部放置刻度标签ax2.xaxis.tick_bottom()# 这看起来不错,而且相当无痛,但你可以做到#切除对角线看起来需要做更多的工作.重要的#这里要知道的是在轴坐标中#在0-1之间,脊椎端点位于以下位置(0,0),(0,1),# (1,0) 和 (1,1).因此,我们只需要把对角线放在每个轴的#个合适的角,只要我们使用# 正确变换并禁用剪辑.d = .015 # 轴坐标中的对角线有多大#个参数传递图,只是为了避免重复kwargs = dict(transform = ax.transAxes,color ='k',clip_on = False)ax.plot((-d,+ d),(-d,+ d),** kwargs)#左上对角线ax.plot((1- d,1 + d),(-d,+ d),** kwargs)#右上对角线kwargs.update(transform=ax2.transAxes) # 切换到底部轴ax2.plot((-d,+ d),(1-d,1 + d),** kwargs)#左下对角线ax2.plot((1 - d, 1 + d), (1 - d, 1 + d), **kwargs) # 右下角对角线#这很酷,那就是现在如果我们改变两者之间的距离通过f.subplots_adjust(hspace = ...)或plt.subplot_tool()#和ax2,# 对角线将相应移动,并保持在提示处他们正在折断"的刺数plt.show()

所需的输出

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. 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. 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

解决方案

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".

The solution to your problem would be to create 6 subplots and apply sharex=True to the respective axes.

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

这篇关于MatPlotLib - 子图的子图或单个图上的多个断轴图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆