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

时间:2013-05-25 10:20:54

标签: python matplotlib

我们有creates figures from input.txt files的代码。我们需要在一个子图中组合其中两个图。图1中的数据将绘制在左侧子图中,右侧子图中的图2将绘制,共享相同的图例,并且在轴x和y中具有相同的比例:

enter image description here

这里有一些示例数据:

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

编辑:@nordev建议的方法有效。现在将ax1和ax2对象传递给新图非常方便,因为它们有更多的信息。 It seems that there is no straightforward way to achieve that

real case has been made available here。要使其正常运行,请运行plot_both.py


EDIT2:更改读取input.txt文件的例程更容易。 Now it supports multiple plots。但问题仍然有效,因为将AxesSubplot视为不同图形,子图等之间容易互换的对象会很棒......

1 个答案:

答案 0 :(得分:10)

这会解决您的问题吗?

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

这给出了如下所示的输出 enter image description here

修改

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

我发现你已经改变了创建绘图的功能,使你的问题的解决方案完全不同,因为你不再试图“合并”来自不同数字的两个子图。你的解决方案与我上面提到的解决方案基本相同,因为两者都在同一个图上创建了两个Axes实例作为子图(给出了所需的布局),然后然后绘图,而不是绘图,然后提取/移动轴,就像你最初的问题一样。

正如我所怀疑的那样,最简单和最简单的解决方案是使相同数字的单个Axes子图,而不是将它们绑定到单独的数字,因为从一个{{1}移动一个Axes实例1}}到另一个不容易完成(如果可能的话),如评论中所指定的。 “原始”问题似乎仍然很难实现,因为简单地向Figure的{​​{1}}添加Axes实例会使您很难自定义所需的布局。

对当前代码的Figure进行一次修改,使图例水平居中,顶部恰好位于轴下方:

_axstack

在这里,应该定制ax.legend(...参数以适应我们图的边界。

BlendedGenericTransform允许x轴和y轴的变换不同,这在许多情况下非常有用。