matplotlib 添加覆盖twinx轴的线的图例

bihw5rsg  于 2023-10-24  发布在  其他
关注(0)|答案(3)|浏览(135)

我有一个python代码。
1.它twinx轴ax和绘图的一些功能在两个轴
1.我在ax1上绘制图例
问题是图例没有覆盖ax2的曲线
可以通过覆盖ax2的线来**自动定位ax上的图例。
请注意,在fig.legend的选项loc="best"是不可用的。我需要在该地区的阴谋自动定位。
Tnx

import matplotlib.pyplot as plt
import numpy as np

# Set the x values for the sine and cosine functions
x = np.linspace(0, 2*np.pi, 100)

# Create the figure and an axis
fig, ax = plt.subplots()
ax2 = ax.twinx()

# Plot the sine and cosine functions on the axis
ax.plot(x, np.sin(x), label='Sine')
ax.plot(x, np.cos(x), label='Cosine')

ax2.plot(x, np.cos(x+1), label='Cosine 2', color="red")
ax2.plot(x, x, label='Cosine 2', color="green")

# Add a title and labels to the axis
ax.set_title('Sine and Cosine Functions')
ax.set_xlabel('X')
ax.set_ylabel('Y')

# Get the line legends from the axis
lines, labels = ax.get_legend_handles_labels()
lines2, labels2 = ax2.get_legend_handles_labels()

# Add a legend to the figure
ax.legend(lines + lines2, labels + labels2, framealpha=1.0)
ax.get_legend().set_zorder(10)

# Display the plot
plt.show()

blog是代码的输出:

wvmv3b1j

wvmv3b1j1#

参考文献:
https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.legend.htmlhttps://matplotlib.org/stable/gallery/misc/zorder_demo.html
默认情况下,legendzorder是最高的,因此如果您希望legend位于所有内容的顶部,则无需修改它。

选项一:

您可以使用Figure对象而不是plt.legend(lines + lines2, labels + labels2, framealpha=1.0, loc='lower left')Axes对象来完成此操作。

选项二:

或者你可以在ax2上设置图例,而不是在ax上设置ax2.legend(lines + lines2, labels + labels2, framealpha=1.0, loc='lower left')。这将返回与选项1相同的结果。

import matplotlib.pyplot as plt
import numpy as np

# Set the x values for the sine and cosine functions
x = np.linspace(0, 2 * np.pi, 100)

# Create the figure and an axis
fig, ax = plt.subplots()
ax2 = ax.twinx()

# Plot the sine and cosine functions on the axis
ax.plot(x, np.sin(x), label='Sine')
ax.plot(x, np.cos(x), label='Cosine')

ax2.plot(x, np.cos(x + 1), label='Cosine 2', color="red")
ax2.plot(x, x, label='Cosine 2', color="green")

# Add a title and labels to the axis
ax.set_title('Sine and Cosine Functions')
ax.set_xlabel('X')
ax.set_ylabel('Y')

# Get the line legends from the axis
lines, labels = ax.get_legend_handles_labels()
lines2, labels2 = ax2.get_legend_handles_labels()

# Add a legend to the figure
plt.legend(lines + lines2, labels + labels2, framealpha=1.0, loc='lower left')

# Display the plot
plt.show()

结果(loc='lower left'loc='lower center'):

更新:

参考:https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.twinx.html
在我之前的答案中,我使用了选项2,在新提供的代码中,我将第36行编辑为ax2.legend(lines + lines2, labels + labels2, framealpha=1.0, loc='lower right'),将第43行编辑为ax22.legend(lines1 + lines22, labels1 + labels22, framealpha=1.0, loc='lower left')
如果你有多个子图,使用Axes对象会更加灵活。

现在可以正常工作了:

jdgnovmf

jdgnovmf2#

谢谢你的回答。
但我的问题更复杂:我需要在平铺的子图中完成这项工作,其中每个图区都是twinx
通过使用plt.label,似乎不可能选择图例的位置。
在下面的代码中,问题就在那里。图例中没有包含字符串的行。
有什么建议吗?

import matplotlib.pyplot as plt
import numpy as np

# Set the x values for the sine and cosine functions
x = np.linspace(0, 2 * np.pi, 100)

# Create the figure and an axis
fig, ax = plt.subplots(2, 1)
ax2 = ax[0].twinx()
ax22 = ax[1].twinx()

# Plot the sine and cosine functions on the axis
ax[0].plot(x, np.sin(x), label='Sine 0')
ax[0].plot(x, np.cos(x), label='Cosine 0')

# Plot the sine and cosine functions on the axis
ax[1].plot(x, np.sin(x), label='Sine')
ax[1].plot(x, np.cos(x), label='Cosine')

ax2.plot(x, np.cos(x + 1), label='Cosine 2', color="red")
ax2.plot(x, x, label='Cosine B', color="green")

ax22.plot(x, np.cos(x + 2), label='Line 2', color="red")
ax22.plot(x, x, label='Cosine 2', color="green")

# Add a title and labels to the axis
ax[0].set_title('Sine and Cosine Functions')
ax[0].set_xlabel('X')
ax[0].set_ylabel('Y')

# Get the line legends from the axis
lines, labels = ax[0].get_legend_handles_labels()
lines2, labels2 = ax2.get_legend_handles_labels()

# Add a legend to the figure
ax[0].legend(lines + lines2, labels + labels2, framealpha=1.0, loc='lower right')

lines1, labels1 = ax[1].get_legend_handles_labels()
lines22, labels22 = ax22.get_legend_handles_labels()

# Add a legend to the figure
ax[1].legend(lines1 + lines22, labels1 + labels22, framealpha=1.0, loc='lower left')

# Display the plot
plt.show()

yiytaume

yiytaume3#

我终于找到了解决办法:
即控制轴的z顺序和具有最高优先级的轴的alpha。
matplotlib函数是:
Axes.set_zorder
https://matplotlib.org/3.2.2/api/_as_gen/matplotlib.axes.Axes.set_zorder.html
&
Patch.set_alpha
https://matplotlib.org/stable/api/_as_gen/matplotlib.patches.Patch.html
用上面的代码替换第三个答案中代码的最后一部分,它会产生预期的结果。

# Get the line legends from the axis
lines, labels = ax[0].get_legend_handles_labels()
lines2, labels2 = ax2.get_legend_handles_labels()

##############################################################################
############################################################################## 
# Set the z-order of axis 2 to a low "priority"
ax2.set_zorder(0)

# Set the z-order of the axis 0 to a higher priority.
# And to make visible axis 2 set the alpha of the background at 0.
ax[0].set_zorder(1)
ax[0].patch.set_alpha(0.0)
 
ax[0].legend(lines + lines2, labels + labels2, framealpha=1.0, loc='lower left')
##############################################################################
##############################################################################
 
lines1, labels1 = ax[1].get_legend_handles_labels()
lines22, labels22 = ax22.get_legend_handles_labels()
 
# Add a legend to the figure
ax22.legend(lines1 + lines22, labels1 + labels22, framealpha=1.0, loc='lower left')
 
# Display the plot
plt.show()

相关问题