【问题标题】:matplotlib: inset axes for multiple boxplotsmatplotlib:多个箱线图的插入轴
【发布时间】:2020-05-19 14:35:20
【问题描述】:

我在 matplotlib 中有一些箱线图,我想使用 inset axes 放大特定的 y 范围 ([0,0.1])。从文档中的example 中我不清楚我应该如何为同一个数字上的多个箱线图执行此操作。我试图修改此示例提供的代码,但有太多不必要的复杂性。我的代码很简单:

# dataToPlot is a list of lists, containing some data. 
plt.figure()
plt.boxplot(dataToPlot)
plt.savefig( 'image.jpeg', bbox_inches=0)

如何添加插入轴并放大两者的第一个箱线图?我怎样才能为两者都做到这一点?

编辑:我尝试了下面的代码,但这是我得到的:

出了什么问题?

# what's the meaning of these two parameters?
fig = plt.figure(1, [5,4])
# what does 111 mean?
ax = fig.add_subplot(111)
ax.boxplot(data)
# ax.set_xlim(0,21)  # done automatically based on the no. of samples, right?
# ax.set_ylim(0,300) # done automatically based on max value in my samples, right?
# Create the zoomed axes
axins = zoomed_inset_axes(ax, 6, loc=1) # zoom = 6, location = 1 (upper right)
axins.boxplot(data)
# sub region of the original image
#here I am selecting the first boxplot by choosing appropriate values for x1 and x2 
# on the y-axis, I'm selecting the range which I want to zoom in, right?
x1, x2, y1, y2 = 0.9, 1.1, 0.0, 0.01
axins.set_xlim(x1, x2)
axins.set_ylim(y1, y2)
# even though it's false, I still see all numbers on both axes, how do I remove them?
plt.xticks(visible=False)
plt.yticks(visible=False)
# draw a bbox of the region of the inset axes in the parent axes and
# connecting lines between the bbox and the inset axes area
# what are fc and ec here? where do loc1 and loc2 come from?
mark_inset(ax, axins, loc1=2, loc2=4, fc="none", ec="0.5")
plt.savefig( 'img.jpeg', bbox_inches=0)

【问题讨论】:

  • 我不确定我是否知道您所说的“同一个数字上的多个箱线图”是什么意思。你有多个子图吗?
  • 不,dataToPlot 包含多个数据样本,plt.boxplot 将其视为:它绘制的箱线图与输入中的样本数量一样多。
  • 那么,你不能再做一个axins=zoomed_inset_axes(ax,6,loc=2) 并为下一个绘图设置不同的坐标范围吗?
  • 我没有设置每个箱线图的位置,所以我不知道它们会出现在哪里。还是我错过了什么?
  • 也许我不完全知道你的问题是什么......你想自动设置缩放图的范围,而不是明确输入 yrange?

标签: python plot matplotlib zooming boxplot


【解决方案1】:

loc 决定了缩放轴的位置,1 代表upper right,2 代表upper left,以此类推。我稍微修改了示例代码以生成多个缩放轴。

import matplotlib.pyplot as plt

from mpl_toolkits.axes_grid1.inset_locator import zoomed_inset_axes
from mpl_toolkits.axes_grid1.inset_locator import mark_inset

import numpy as np

def get_demo_image():
    from matplotlib.cbook import get_sample_data
    import numpy as np
    f = get_sample_data("axes_grid/bivariate_normal.npy", asfileobj=False)
    z = np.load(f)
    # z is a numpy array of 15x15
    return z, (-3,4,-4,3)


fig = plt.figure(1, [5,4])
ax = fig.add_subplot(111)

# prepare the demo image
Z, extent = get_demo_image()
Z2 = np.zeros([150, 150], dtype="d")
ny, nx = Z.shape
Z2[30:30+ny, 30:30+nx] = Z

# extent = [-3, 4, -4, 3]
ax.imshow(Z2, extent=extent, interpolation="nearest",
          origin="lower")

axins = zoomed_inset_axes(ax, 6, loc=1) # zoom = 6
axins.imshow(Z2, extent=extent, interpolation="nearest",
             origin="lower")

# sub region of the original image
x1, x2, y1, y2 = -1.5, -0.9, -2.5, -1.9
axins.set_xlim(x1, x2)
axins.set_ylim(y1, y2)

axins1 = zoomed_inset_axes(ax, 8, loc=2) # zoom = 8
axins1.imshow(Z2, extent=extent, interpolation="nearest",
             origin="lower")

# sub region of the original image
x1, x2, y1, y2 = -1.2, -0.9, -2.2, -1.9
axins1.set_xlim(x1, x2)
axins1.set_ylim(y1, y2)

plt.xticks(visible=False)
plt.yticks(visible=False)

# draw a bbox of the region of the inset axes in the parent axes and
# connecting lines between the bbox and the inset axes area
mark_inset(ax, axins, loc1=2, loc2=4, fc="none", ec="0.5")
mark_inset(ax, axins1, loc1=2, loc2=4, fc="none", ec="0.5")

plt.draw()
plt.show()

编辑1:

同样,您也可以在箱线图中添加缩放轴。这是一个例子

from pylab import *
from mpl_toolkits.axes_grid1.inset_locator import zoomed_inset_axes
from mpl_toolkits.axes_grid1.inset_locator import mark_inset

# fake up some data
spread = rand(50) * 100 
center = ones(25) * 50
flier_high = rand(10) * 100 + 100
flier_low = rand(10) * -100
data = concatenate((spread, center, flier_high, flier_low), 0)

# fake up some more data
spread= rand(50) * 100
center = ones(25) * 40
flier_high = rand(10) * 100 + 100
flier_low = rand(10) * -100
d2 = concatenate( (spread, center, flier_high, flier_low), 0 )
data.shape = (-1, 1)
d2.shape = (-1, 1)
data = [data, d2, d2[::2,0]]

# multiple box plots on one figure
fig = plt.figure(1, [5,4])
ax = fig.add_subplot(111)
ax.boxplot(data)
ax.set_xlim(0.5,5)
ax.set_ylim(0,300)

# Create the zoomed axes
axins = zoomed_inset_axes(ax, 3, loc=1) # zoom = 3, location = 1 (upper right)
axins.boxplot(data)

# sub region of the original image
x1, x2, y1, y2 = 0.9, 1.1, 125, 175
axins.set_xlim(x1, x2)
axins.set_ylim(y1, y2)
plt.xticks(visible=False)
plt.yticks(visible=False)

# draw bboxes of the two regions of the inset axes in the parent axes and
# connect lines between the bbox and the inset axes area
mark_inset(ax, axins, loc1=2, loc2=4, fc="none", ec="0.5")

show() 

编辑2

如果分布是异质的,即大多数值很小而很少有非常大的值,上述缩放过程可能不起作用,因为它会同时缩放xy 轴。在这种情况下,最好将y-axis 的比例更改为log

from pylab import *

# fake up some data
spread = rand(50) * 1
center = ones(25) * .5
flier_high = rand(10) * 100 + 100
flier_low = rand(10) * -100
data = concatenate((spread, center, flier_high, flier_low), 0)

# fake up some more data
spread = rand(50) * 1
center = ones(25) * .4
flier_high = rand(10) * 100 + 100
flier_low = rand(10) * -100
d2 = concatenate( (spread, center, flier_high, flier_low), 0 )
data.shape = (-1, 1)
d2.shape = (-1, 1)
data = [data, d2, d2[::2,0]]

# multiple box plots on one figure
fig = plt.figure(1, [5,4]) # Figure Size
ax = fig.add_subplot(111)  # Only 1 subplot 
ax.boxplot(data)
ax.set_xlim(0.5,5)
ax.set_ylim(.1,300)
ax.set_yscale('log')

show()

【讨论】:

  • 谢谢。这方面的文档对于我的目的来说仍然太复杂了。我编辑了我的原始帖子以强调我现在正在做的事情,并从在线示例中删除了所有不必要的行。您能否修改我的代码,以便我可以看到我实际上应该做什么?谢谢。
  • 检查编辑的答案。如果您在理解代码的任何特定部分有困难,请告诉我。
  • 谢谢。我编辑了我的帖子并添加了您的代码输出以及对所使用的一些参数的问题。
  • 您输入了y1, y2 = 0.0, 0.01zoom = 6。这意味着在您的缩放 y 轴中是 0.06,它仍然远小于主轴中的 [0-250] 范围。您必须增加缩放或 y1、y2 值。
  • 好的,谢谢。它似乎没有像我预期的那样工作。我想显示中位数在哪里,也就是我想显示蓝色矩形所在的范围,但是当我放大太多时,它也会在x轴上放大,有点乱。
猜你喜欢
  • 1970-01-01
  • 2016-06-22
  • 1970-01-01
  • 1970-01-01
  • 2020-09-04
  • 1970-01-01
  • 1970-01-01
  • 2019-12-07
  • 1970-01-01
相关资源
最近更新 更多