当前位置: 首页 > 知识库问答 >
问题:

如何创建ax。legend()方法,用于不需要用户传递图例手柄的轮廓曲线图?

张鸿宝
2023-03-14

我希望能打电话

ax.legend()

在包含contourf绘图的轴上,自动获取图例(参见下面的绘图示例)。

我知道如何使用代理为contourf图创建图例条目,请参阅下面的代码,这在本Q中已经讨论过

绘图生成(比本例中更复杂的绘图)发生在一个包中,用户可以访问,并且根据绘图的不同,可能更喜欢某些轴而不是其他轴来绘制图例。如果调用ax就好了。legend()可以很简单,不需要使用代理和显式传递句柄。这会自动用于普通图、散点图、历史图等,但tourtf不接受label作为kwarg,并且没有自己的句柄,因此我需要创建一个代理(在这种情况下为矩形面片)。

但是我怎么能附加/属性/...代理旁边的标签到contourf情节或,这样ax.legend()可以像其他类型一样自动访问它们的阴谋?

import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
from matplotlib.colors import LinearSegmentedColormap


########################
# not accessed by User #
########################

def basic_cmap(color):
    return LinearSegmentedColormap.from_list(color, ['#ffffff', color])
cmap1 = basic_cmap('C0')
cmap2 = basic_cmap('C1')

x = np.linspace(0, 10, 50)
mvn1 = stats.multivariate_normal(mean=[4, 4])
mvn2 = stats.multivariate_normal(mean=[6, 7])
X, Y = np.meshgrid(x, x)
Z1 = [[mvn1.pdf([x1, x2]) for x1 in x] for x2 in x]
Z2 = [[mvn2.pdf([x1, x2]) for x1 in x] for x2 in x]
Z1 = Z1 / np.max(Z1)
Z2 = Z2 / np.max(Z2)

fig, axes = plt.subplots(2, 2, sharex='col', sharey='row')
for i, row in enumerate(axes):
    for j, ax in enumerate(row):
        cont1 = ax.contourf(X, Y, Z1, [0.05, 0.33, 1], cmap=cmap1, alpha=0.7)
        cont2 = ax.contourf(X, Y, Z2, [0.05, 0.33, 1], cmap=cmap2, alpha=0.7)


###################################
# User has access to fig and axes #
###################################

proxy1 = plt.Rectangle((0, 0), 1, 1, fc=cmap1(0.999), ec=cmap1(0.33), alpha=0.7, linewidth=3)
proxy2 = plt.Rectangle((0, 0), 1, 1, fc=cmap2(0.999), ec=cmap2(0.33), alpha=0.7, linewidth=3)

# would like this without passing of handles and labels
axes[0][-1].legend(handles=[proxy1, proxy2], labels=['foo', 'bar'])  


plt.savefig("contour_legend.png")
plt.show()

共有1个答案

舒永嘉
2023-03-14

好吧,我做了更多的斑点,找到了一个解决方案,毕竟这非常简单,但我必须深入研究matplotlib。图例以获得正确的想法。在\u get\u legend\u handles中,它显示了如何收集句柄:

    for ax in axs:
        handles_original += (ax.lines + ax.patches +
                             ax.collections + ax.containers)

所以我所缺少的就是将标签传递给代理,并将代理传递给ax。修补程序

        # pass labels to proxies and place proxies in loop
        proxy1 = plt.Rectangle((0, 0), 1, 1, fc=cmap1(0.999), ec=cmap1(0.33), 
                               alpha=0.7, linewidth=3, label='foo')
        proxy2 = plt.Rectangle((0, 0), 1, 1, fc=cmap2(0.999), ec=cmap2(0.33), 
                               alpha=0.7, linewidth=3, label='bar')

        # pass proxies to ax.patches
        ax.patches += [proxy1, proxy2]


###################################
# User has access to fig and axes #
###################################

# no passing of handles and labels anymore
axes[0][-1].legend()
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
from matplotlib.colors import LinearSegmentedColormap


########################
# not accessed by User #
########################

def basic_cmap(color):
    return LinearSegmentedColormap.from_list(color, ['#ffffff', color])
cmap1 = basic_cmap('C0')
cmap2 = basic_cmap('C1')

x = np.linspace(0, 10, 50)
mvn1 = stats.multivariate_normal(mean=[4, 4])
mvn2 = stats.multivariate_normal(mean=[6, 7])
X, Y = np.meshgrid(x, x)
Z1 = [[mvn1.pdf([x1, x2]) for x1 in x] for x2 in x]
Z2 = [[mvn2.pdf([x1, x2]) for x1 in x] for x2 in x]
Z1 = Z1 / np.max(Z1)
Z2 = Z2 / np.max(Z2)

fig, axes = plt.subplots(2, 2, sharex='col', sharey='row')
for i, row in enumerate(axes):
    for j, ax in enumerate(row):
        cont1 = ax.contourf(X, Y, Z1, [0.05, 0.33, 1], cmap=cmap1, alpha=0.7)
        cont2 = ax.contourf(X, Y, Z2, [0.05, 0.33, 1], cmap=cmap2, alpha=0.7)

        # pass labels to proxies and place proxies in loop
        proxy1 = plt.Rectangle((0, 0), 1, 1, fc=cmap1(0.999), ec=cmap1(0.33), 
                               alpha=0.7, linewidth=3, label='foo')
        proxy2 = plt.Rectangle((0, 0), 1, 1, fc=cmap2(0.999), ec=cmap2(0.33), 
                               alpha=0.7, linewidth=3, label='bar')

        # pass proxies to ax.patches
        ax.patches += [proxy1, proxy2]


###################################
# User has access to fig and axes #
###################################

# no passing of handles and labels anymore
axes[0][-1].legend()  


plt.savefig("contour_legend_solved.png")
plt.show()

这将产生与问题中所示相同的图像。

对不起,毕竟我自己能想出一个解决方案,但也许这对将来的其他人会有帮助。

 类似资料:
  • 我有和这篇文章一样的问题:用户想要删除图例中重复的条目: 停止matplotlib在图例中重复标签 答案也适用于我,但是,当我使用它时,图例格式完全丢失。当我使用斧头时会发生这种情况。图例(句柄、标签)方法。以下代码(复制自http://matplotlib.org/examples/pylab_examples/legend_demo.html)说明了这个问题: 欢迎任何建议 编辑1:更正输入错

  • 我有3个maven项目A、B、C。A是B的父项目,B是C的父项目。所有概要文件都在pom中定义。项目A的xml。 在项目C中,我试图根据所选概要文件在spring测试上下文中选择属性文件(在src/test/resources下)。对于回归测试,我们有两个属性文件: 本地应用程序测试。属性 在我们的Windows开发系统上,选定的配置文件将是“本地”的,相应地在服务器上也是如此。选择“本地”配置文

  • 问题内容: 我只是将一个工作程序重写为一个类中的函数,然后一切都搞砸了。 首先 ,在课程的部分中,我用声明了一堆变量。 通过使用该函数,是否应该能够在类的每个函数中访问/修改这些变量?换句话说,通过声明我已经做了这些变量,在类范围内的全局变量对吗? 如果没有,我该如何处理自我? 其次 ,如何正确将参数传递给类? 第三 ,如何在类范围之外调用类的函数? 第四 ,如何在另一个实例中创建的实例,并将变量

  • 问题内容: 有没有一种简单的方法来获取绘制如下轮廓线的(x,y)值: 问题答案: 查看返回的ContourSet的collections属性。特别是第一个集合的get_paths()方法返回组成每个线段的成对点。 要获取坐标的NumPy数组,请使用属性。

  • 本文向大家介绍用python建立两个Y轴的XY曲线图方法,包括了用python建立两个Y轴的XY曲线图方法的使用技巧和注意事项,需要的朋友参考一下 想把python提取出来的 加载点反力和某个单元的应力画在同一个XY曲线图上,由于两者数量级差太远,故而需要建立有两个Y轴的XY曲线图。 效果为: 代码如下: 用于提取数据的两个文件,内容如下: Load-Time.txt RF-Mises-Time-

  • 我想在一个可以更新的文件中创建一组别名,然后调用别名,以便执行该文件,并在当前会话中为我提供新的别名。最终,我希望这些别名在PS启动时自动可用,所以我使用的是将它们放入。现在看来: 我如何做到这一点,以便在启动时加载别名,同时也可以使用别名更新别名,并将其带到当前会话中?