如何在 Matplotlib 中使用带有形状内文本的自定义标记?

2024-01-10

背景

在 Matplotlib 中,我们可以使用 mathtext 作为标记来渲染字符串$ ..... $ (参考文献1 https://matplotlib.org/3.2.1/api/markers_api.html)

Question

有什么方法可以将此文本封装在圆形或矩形框或任何不同的形状中吗?类似于如图所示的注册符号here https://maxcdn.icons8.com/Share/icon/p1em/Business/registered_trademark1600.png

I want to use this marker on a plot as shown below: Text '$T$' is used in this plot, I want the text to be enclosed in a circle or rectangle

该图中使用了文本“$T$”,我希望文本包含在圆形或矩形中。

Solution

As suggested in the comments of the answer, I have plotted a square marker of a bit larger size before the text marker. This resolved the issue. The final figure is shown below:


编辑:最简单的方法是简单地将补丁放置在与标记相同的位置,成为所需的“框架”。只要确保他们有一个较低的zorder这样它们就不会覆盖数据点。

更复杂的方法如下:

你可以打补丁。这是我用来制作自定义问号的示例:

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.markers as m

fig, ax = plt.subplots()
lim = -5.8, 5.7
ax.set(xlim = lim, ylim = lim)

marker_obj = m.MarkerStyle('$?$') #Here you place your letter
path = marker_obj.get_path().transformed(marker_obj.get_transform())

path._vertices = np.array(path._vertices)*8 #To make it larger
patch = mpl.patches.PathPatch(path, facecolor="cornflowerblue", lw=2)
ax.add_patch(patch)

def translate_verts(patch, i=0, j=0, z=None):
    patch._path._vertices = patch._path._vertices + [i, j]

def rescale_verts(patch, factor = 1):
    patch._path._vertices = patch._path._vertices * factor

#translate_verts(patch, i=-0.7, j=-0.1)

circ = mpl.patches.Arc([0,0], 11, 11,
                       angle=0.0, theta1=0.0, theta2=360.0,
                       lw=10, facecolor = "cornflowerblue",
                       edgecolor = "black")
ax.add_patch(circ)#One of the rings around the questionmark

circ = mpl.patches.Arc([0,0], 10.5, 10.5,
                       angle=0.0, theta1=0.0, theta2=360.0,
                       lw=10, edgecolor = "cornflowerblue")
ax.add_patch(circ)#Another one of the rings around the question mark

circ = mpl.patches.Arc([0,0], 10, 10,
                       angle=0.0, theta1=0.0, theta2=360.0,
                       lw=10, edgecolor = "black")
ax.add_patch(circ)



if __name__ == "__main__":
    ax.axis("off")
    ax.set_position([0, 0, 1, 1])
    fig.canvas.draw()
    #plt.savefig("question.png", dpi=40)
    plt.show()

编辑,第二个答案: 创建由其他补丁组成的自定义补丁:

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import mpl_toolkits.mplot3d.art3d as art3d


class PlanetPatch(mpl.patches.Circle):
    """
        This class combines many patches to make a custom patch
        The best way to reproduce such a thing is to read the
        source code for all patches you plan on combining.
        Also make use of ratios as often as possible to maintain
        proportionality between patches of different sizes"""
    cz = 0
    def __init__(self, xy, radius,
                 color = None, linewidth = 20,
                 edgecolor = "black", ringcolor = "white",
                 *args, **kwargs):
        ratio = radius/6
        mpl.patches.Circle.__init__(self, xy, radius,
                                    linewidth = linewidth*ratio,
                                    color = color,
                                    zorder = PlanetPatch.cz,
                                    *args, **kwargs)
        self.set_edgecolor(edgecolor)
        xy_ringcontour = np.array(xy)+[0, radius*-0.2/6]
        self.xy_ringcontour = xy_ringcontour - np.array(xy)
        self.ring_contour = mpl.patches.Arc(xy_ringcontour,
                                15*radius/6, 4*radius/6,
                                angle =10, theta1 = 165,
                                theta2 = 14.5,
                                fill = False, 
                                linewidth = 65*linewidth*ratio/20,
                                zorder = 1+PlanetPatch.cz)

        self.ring_inner = mpl.patches.Arc(xy_ringcontour,
                                 15*radius/6, 4*radius/6,
                                 angle = 10, theta1 = 165 ,
                                 theta2 = 14.5,fill = False,
                                 linewidth = 36*linewidth*ratio/20,
                                 zorder = 2+PlanetPatch.cz)

        self.top = mpl.patches.Wedge([0,0], radius, theta1 = 8,
                                     theta2 = 192,
                                     zorder=3+PlanetPatch.cz)
        self.xy_init = xy
        self.top._path._vertices=self.top._path._vertices+xy

        self.ring_contour._edgecolor = self._edgecolor
        self.ring_inner.set_edgecolor(ringcolor)
        self.top._facecolor = self._facecolor

    def add_to_ax(self, ax):
        ax.add_patch(self)
        ax.add_patch(self.ring_contour)
        ax.add_patch(self.ring_inner)
        ax.add_patch(self.top)


    def translate(self, dx, dy):
        self._center = self.center + [dx,dy]
        self.ring_inner._center = self.ring_inner._center +[dx, dy]
        self.ring_contour._center = self.ring_contour._center + [dx,dy]
        self.top._path._vertices = self.top._path._vertices + [dx,dy]

    def set_xy(self, new_xy):
        """As you can see all patches have different ways
            to have their positions updated"""
        new_xy = np.array(new_xy)
        self._center = new_xy
        self.ring_inner._center = self.xy_ringcontour + new_xy
        self.ring_contour._center = self.xy_ringcontour + new_xy
        self.top._path._vertices += new_xy - self.xy_init 

fig  = plt.figure(figsize=(6, 6))
ax = fig.add_subplot()
lim = -8.5, 8.6
ax.set(xlim = lim, ylim = lim,
       facecolor = "black")
planets = []
colors = mpl.colors.cnames
colors = [c for c in colors]
for x in range(100):
    xy = np.random.randint(-7, 7, 2)
    r = np.random.randint(1, 15)/30
    color = np.random.choice(colors)
    planet = PlanetPatch(xy, r, linewidth = 20,
                         color = color,
                         ringcolor = np.random.choice(colors),
                         edgecolor = np.random.choice(colors))
    planet.add_to_ax(ax)
    planets.append(planet)


fig.canvas.draw()
#plt.savefig("planet.png", dpi=10)
plt.show()

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Matplotlib 中使用带有形状内文本的自定义标记? 的相关文章

随机推荐

  • NaN 作为字典中的键

    谁能向我解释以下行为 gt gt gt import numpy as np gt gt gt np nan 5 np nan 5 gt gt gt float64 np nan 5 float64 np nan KeyError nan
  • 切换到共享运行时后 Office 插件加载失败

    我跟着配置您的 Office 加载项以使用共享 JavaScript 运行时 https learn microsoft com en us office dev add ins develop configure your add in
  • 如何使用searchkick根据某些条件进行索引

    我正在使用searchkick 和rails4 我有一个活动记录 People 其属性为 a b c 如何仅当 b 等于 type1 时才建立索引 否则不建立索引 目前我所知道的是 def search data a a b b c c e
  • java等待光标显示问题

    我在应用程序中显示等待光标时遇到问题 只要鼠标位于定义其自身光标的面板上方 等待光标就不会出现 如果面板不改变光标 则会出现等待光标 我附上 SSCE 来准确解释我的问题 public class BusyCursorTest extend
  • VS 2017 中的 MySQL 和 MVC 实体框架无法正常工作

    我正在尝试启动 MVC EF Visual Studio 2017 项目 我在本地实例上使用 MySQL 设置了数据连接 但是当我创建 ADO net 数据模型时 出现图中所示的错误 这里还有另一篇文章 无法对实体框架 6 使用 MySQL
  • 对数据库的访问进行队列以避免多个缓存项

    我有一个与音乐相关的 ASP NET 网站 它在第一次请求时缓存数据库中的大量静态信息 有时 应用程序负载较重时会重置应用程序并清除缓存 然后所有 http 请求都会转到数据库以检索静态数据并将其缓存以供其他请求使用 如何确保只有一个请求进
  • 表达式树生成的 IL 是否经过优化?

    好吧 这只是好奇心 对现实世界没有帮助 我知道使用表达式树 您可以像常规 C 编译器一样即时生成 MSIL 由于编译器可以决定优化 我很想问在执行期间生成的 IL 的情况如何Expression Compile 基本上有两个问题 因为在编译
  • ResizeObserver 一 vs 多性能

    The 调整大小观察者 https wicg github io ResizeObserver has an 观察 https wicg github io ResizeObserver dom resizeobserver observe
  • 保留源 shell 脚本而不退出终端

    我正在编写一个 shell 脚本来保存一些击键并避免拼写错误 我想将脚本保留为单个文件 该文件调用内部方法 函数并在出现问题时终止函数without离开航站楼 my script sh bin bash exit if no git if
  • 为什么方法定义返回符号?

    当你定义一个方法时 它会返回一个与该方法同名的符号 这有道理吗 或者它只是作为您创建它的验证 Like so def something end gt something IRb always显示调用结果inspect计算的最后一个表达式的
  • StringBuilder容量()

    我注意到capacity方法返回StringBuilder没有逻辑的能力 方式 有时它的值等于字符串长度 有时它更大 有没有一个方程式可以知道它的逻辑是什么 我将尝试用一些例子来解释这一点 public class StringBuilde
  • 编译错误:“stddef.h:没有这样的文件或目录”

    每当我尝试编译此代码时 总是会出现以下错误 In file included from usr include wchar h 6 0 from usr lib gcc i686 pc cygwin 4 9 2 include c cwch
  • 在 Inno Setup 中将字符串编码为 Base64(Inno Setup 的 Unicode 版本)

    Problem 我尝试使用帕斯卡函数EncodeStringBase64 假设 Inno Setup 可以访问 Pascal 标准库 但它无法找到它并提供一个Unknown Identifier error https www freepa
  • 使用 GDI+ 将修改后的图像保存到原始文件

    我正在从文件加载位图图像 当我尝试将图像保存到另一个文件时 出现以下错误 GDI 中发生一般错误 我相信这是因为文件被图像对象锁定 好的 所以尝试调用 Image Clone 函数 这仍然锁定文件 唔 接下来 我尝试从 FileStream
  • 删除目录下的所有文件

    我需要使用 Qt 删除目录中的所有文件 该目录中的所有文件都将具有扩展名 txt 我不想删除目录本身 有谁知道我该怎么做 我看过 QDir 但没有运气 比约恩斯的答案被调整为不会永远循环 QString path whatever QDir
  • 版本 4.0.0 文档中的示例中的 Identity Server 范围无效

    我正在使用 IdentityServer4 遵循以下文档https identityserver4 readthedocs io en latest quickstarts 1 client credentials html https i
  • OWL RDF/TTL 根据属性创建类的实例成员

    我正在尝试设计一个本体 该本体将根据产品组件对产品进行分类 在下面的例子中我有一堂课Ingredient有一个实例eggs 我想添加apple tart不包含的所有类别的产品eggs 所以在这种情况下apple tart将被添加到班级中Gl
  • 限制 UITextView 中的行数

    我很清楚有人问过这个问题 但我找不到有效的答案 使用先前解决方案的组合 我想出了以下代码 BOOL textView UITextView textView shouldChangeTextInRange NSRange range rep
  • Google App Engine 上的 CloudSQL PDO(unix_socket) 问题

    我正在尝试从 App Engine 连接到我的 CloudSQL 实例 我的设置方法是使用静态 IP 我可以使用它从 App Engine 外部 即在我的开发环境中 连接到它 但是 当应用程序在 GAE 中运行时 连接到数据库的唯一方法是使
  • 如何在 Matplotlib 中使用带有形状内文本的自定义标记?

    背景 在 Matplotlib 中 我们可以使用 mathtext 作为标记来渲染字符串 参考文献1 https matplotlib org 3 2 1 api markers api html Question 有什么方法可以将此文本封