matplotlib:结合不同的数字并将它们放在一个共同的图例中

Sau*_*tro 12 python matplotlib

我们有一个代码,用于从input.txt文件创建数字.我们需要在一个子图中组合其中两个图.图1中的数据将绘制在左侧子图中,右侧子图中的图2将绘制,共享相同的图例,并且在轴x和y中具有相同的比例:

在此输入图像描述

这里有一些示例数据:

x  = [ 1, 2, 3, 5, 10, 100, 1000 ]
y1 = [ 1, 0.822, 0.763, 0.715, 0.680, 0.648, 0.645 ]
y2 = [ 1, 0.859, 0.812, 0.774, 0.746, 0.721, 0.718 ]

import matplotlib.pyplot as plt
# mode 01 from one case
fig1 = plt.figure()
ax1 = fig1.add_subplot(111)
ax1.plot( x, y1, label='mode 01' )
# mode 01 from other case
fig2 = plt.figure()
ax2 = fig2.add_subplot(111)
ax2.plot( x, y2, label='mode 01' )
Run Code Online (Sandbox Code Playgroud)

编辑:@nordev建议的方法有效.现在将ax1和ax2对象传递给新图非常方便,因为它们有更多的信息.似乎没有直接的方法来实现这一目标.

实际情况下,已提供在这里.为了使它工作,请运行plot_both.py.


EDIT2:更改读取input.txt文件的例程更容易.现在它支持多个图.但问题仍然有效,因为AxesSubplot在不同的图形,子图等中将它视为一个易于互换的对象会很棒......

sod*_*odd 11

这会解决您的问题吗?

x  = [ 1, 2, 3, 5, 10, 100, 1000 ]
y1 = [ 1, 0.822, 0.763, 0.715, 0.680, 0.648, 0.645 ]
y2 = [ 1, 0.859, 0.812, 0.774, 0.746, 0.721, 0.718 ]

import matplotlib.pyplot as plt
from matplotlib.transforms import BlendedGenericTransform
# mode 01 from one case
fig1 = plt.figure()
ax1 = fig1.add_subplot(111)
line1, = ax1.plot( x, y1, label='mode 01' )
# mode 01 from other case
fig2 = plt.figure()
ax2 = fig2.add_subplot(111)
line2, = ax2.plot( x, y2, label='mode 01' )

# Create new figure and two subplots, sharing both axes
fig3, (ax3, ax4) = plt.subplots(1,2,sharey=True, sharex=True,figsize=(10,5))

# Plot data from fig1 and fig2
line3, = ax3.plot(line1.get_data()[0], line1.get_data()[1])
line4, = ax4.plot(line2.get_data()[0], line2.get_data()[1])
# If possible (easy access to plotting data) use
# ax3.plot(x, y1)
# ax4.lpot(x, y2)

ax3.set_ylabel('y-axis')
ax3.grid(True)
ax4.grid(True)

# Add legend
fig3.legend((line3, line4),
            ('label 3', 'label 4'),
            loc = 'upper center',
            bbox_to_anchor = [0.5, -0.05],
            bbox_transform = BlendedGenericTransform(fig3.transFigure, ax3.transAxes))
# Make space for the legend beneath the subplots
plt.subplots_adjust(bottom = 0.2)
# Show only fig3
fig3.show()
Run Code Online (Sandbox Code Playgroud)

这给出了如下所示的输出 在此输入图像描述

编辑

查看上传的zip文件中的代码,我会说大部分要求的功能都已实现?

我看到你已经改变了创建绘图的功能,使你的问题的解决方案完全不同,因为你不再试图"合并"来自不同数字的两个子图.您的解决方案基本上与我上面提到的解决方案相同,在这两种Axes情况下,两个实例都在同一个图上创建了子图(给出了所需的布局),然后绘制,而不是绘图,然后提取/移动轴,因为你的问题最初是关于.

正如我所怀疑的那样,最简单和最简单的解决方案是制作Axes相同图形的单个子图,而不是将它们绑定到单独的图形,因为将一个Axes实例从一个实例移动Figure到另一个实例并不容易实现(如果可能的话),如指定的那样在评论中."原始"的问题似乎仍然很难做到,因为只需添加一个Axes实例到Figure_axstack使得它很难定制所需的布局.

ax.legend(...对当前代码进行一处修改,使图例水平居中,顶部恰好位于轴下方:

# Add this line
from matplotlib.transforms import BlendedGenericTransform

# Edit the function call to use the BlendedGenericTransform
ax.legend(loc='upper center',
          ncol=7,
          labelspacing=-0.7,
          columnspacing=0.75,
          fontsize=8,
          handlelength=2.6,
          markerscale=0.75,
          bbox_to_anchor=(0.5, -0.05),
          bbox_transform=BlendedGenericTransform(fig.transFigure, ax.transAxes))
Run Code Online (Sandbox Code Playgroud)

在这里,bbox_to_anchor应该定制参数以适应我们的图的边界.

BlendedGenericTransform允许的x轴和y轴的变换是不同的,可以是在许多情况下是非常有用的.

  • @SaulloCastro根据[此评论](http://stackoverflow.com/questions/6309472/matplotlib-can-i-create-axessubplot-objects-then-add-them-to-a-figure-instance#comment18919455_6309636) Joe Kington(12月12日),故意不应该在各个数字之间分享`Axes`实例,这使得你的请求很难完成. (3认同)