在 matplotlib 轴上设置科学限制后调整指数文本

2023-12-23

目前,如果我将 matplotlib y 轴刻度标签设置为科学模式,它会在表单 y 轴顶部给出一个指数1e-5

我想调整这个来阅读r'$\mathregular{10^{-5}}$'这样就可以很好地打印出来。

这是我的示例代码:

# Create a figure and axis
fig, ax = plt.subplots()

# Plot 100 random points 
# the y values of which are very small
ax.scatter(np.random.rand(100), np.random.rand(100)/100000.0)

# Set the y limits appropriately
ax.set_ylim(0, 1/100000.0)

# Change the y ticklabel format to scientific format
ax.ticklabel_format(axis='y', style='sci', scilimits=(-2, 2))

# Get the offset value
offset = ax.yaxis.get_offset_text()

# Print it out
print '1st offset printout: {}'.format(offset)

# Run plt.tight_layout()
plt.tight_layout()

# Print out offset again - you can see the value now!
print '2nd offset printout: {}'.format(offset)

# Change it to latex format
offset.set_text(r'$\mathregular{10^{-5}}$')

# Print it out
print '3rd offset printout: {}'.format(offset)

# Add some text to the middle of the figure just to 
# check that it isn't the latex format that's the problem
ax.text(0.5, 0.5/100000.0, r'$\mathregular{10^{-2}}$')

# And show the figure
plt.show()

我的输出如下所示:

1st offset printout: Text(0,0.5,u'')
2nd offset printout: Text(0,636.933,u'1e\u22125')
3rd offset printout: Text(0,636.933,u'$\\mathregular{10^{-5}}$')

可以找到代码和输出图here http://nbviewer.ipython.org/gist/HappyPenguin/9718c2031413c227200d.

有两个奇怪的地方:一个是我无法覆盖 y 轴顶部的 1e-5 (这是目标),另一个是我必须运行plt.tight_layout()以便将 unicode 值视为偏移量。

谁能告诉我哪里错了?

谢谢

编辑:最初的问题没有明确表示我想自动检测当前计算的指数ticklabel_format。因此,它不应该将设置的字符串传递给偏移文本,而是应该自动检测该值并相应地调整乳胶字符串。


基于@edsmith的答案,一种可能的解决方法是获取偏移文本,将其转换为乳胶字符串,关闭偏移并在轴的顶部添加该字符串。

def format_exponent(ax, axis='y'):

    # Change the ticklabel format to scientific format
    ax.ticklabel_format(axis=axis, style='sci', scilimits=(-2, 2))

    # Get the appropriate axis
    if axis == 'y':
        ax_axis = ax.yaxis
        x_pos = 0.0
        y_pos = 1.0
        horizontalalignment='left'
        verticalalignment='bottom'
    else:
        ax_axis = ax.xaxis
        x_pos = 1.0
        y_pos = -0.05
        horizontalalignment='right'
        verticalalignment='top'

    # Run plt.tight_layout() because otherwise the offset text doesn't update
    plt.tight_layout()
    ##### THIS IS A BUG 
    ##### Well, at least it's sub-optimal because you might not
    ##### want to use tight_layout(). If anyone has a better way of 
    ##### ensuring the offset text is updated appropriately
    ##### please comment!

    # Get the offset value
    offset = ax_axis.get_offset_text().get_text()

    if len(offset) > 0:
        # Get that exponent value and change it into latex format
        minus_sign = u'\u2212'
        expo = np.float(offset.replace(minus_sign, '-').split('e')[-1])
        offset_text = r'x$\mathregular{10^{%d}}$' %expo

        # Turn off the offset text that's calculated automatically
        ax_axis.offsetText.set_visible(False)

        # Add in a text box at the top of the y axis
        ax.text(x_pos, y_pos, offset_text, transform=ax.transAxes,
               horizontalalignment=horizontalalignment,
               verticalalignment=verticalalignment)
    return ax

请注意,您应该能够通过调用来使用偏移文本的位置pos = ax_axis.get_offset_text().get_position()但这些值不是轴单位(它们可能是像素单位 - 感谢@EdSmith - 因此不是很有帮助)。因此我刚刚设置了x_pos and y_pos根据我们正在查看的轴的值。

我还编写了一个小函数来自动检测适当的 x 和 y 限制(尽管我知道 matplotlib 有很多奇特的方法可以做到这一点)。

def get_min_max(x, pad=0.05):
    '''
    Find min and max values such that
    all the data lies within 90% of
    of the axis range
    '''
    r = np.max(x) - np.min(x)
    x_min = np.min(x) - pad * r
    x_max = np.max(x) + pad * r
    return x_min, x_max

因此,要更新问题中的示例(稍作更改以使两个轴都需要指数):

import matplotlib.pylab as plt
import numpy as np

# Create a figure and axis
fig, ax = plt.subplots()

# Plot 100 random points that are very small
x = np.random.rand(100)/100000.0
y = np.random.rand(100)/100000.0
ax.scatter(x, y)

# Set the x and y limits
x_min, x_max = get_min_max(x)
ax.set_xlim(x_min, x_max)
y_min, y_max = get_min_max(y)    
ax.set_ylim(y_min, y_max)

# Format the exponents nicely
ax = format_exponent(ax, axis='x')
ax = format_exponent(ax, axis='y')

# And show the figure
plt.show()

可以使用带有显示代码输出的 ipython 笔记本的要点here http://nbviewer.ipython.org/gist/HappyPenguin/85d4483bfc686bdbd52b.

我希望这有帮助!

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

在 matplotlib 轴上设置科学限制后调整指数文本 的相关文章

随机推荐

  • 使用ggplot、gtable和cowplot固定图例框的宽度

    我想用 R 制作一个绘图 看起来像用 Mac 的 Numbers 制作的示例 我正在努力处理情节和图例框之间的空间 这是我想要实现的目标的示例 在一些用户的帮助下 请参阅帖子末尾以供参考 我已经非常接近了 这是我当前的功能 library
  • 在 Javascript 中实现后退按钮“警告”以在 Flex 中使用

    我有一个 Flex 应用程序 如果用户按下后退按钮 我想向他们发出警告 这样他们就不会错误地离开该应用程序 我知道由于跨浏览器不兼容 这不能完全在 Actionscript 中完成 我正在寻找的只是捕获后退按钮的 Javascript 实现
  • 带有 Node.js 和 Express 的基本网络服务器,用于提供 html 文件和资产

    我正在做一些前端实验 我想要一个非常基本的网络服务器来快速启动一个项目并提供文件 一个index html文件 一些css js img文件 所以我试图用node js和express做一些东西 我已经玩过了 但这次我不想使用渲染引擎 因为
  • 是否有可能拥有 JSON.stringify 保留功能?

    拿这个对象 x key1 xxx key2 function return this key1 如果我这样做 y JSON parse JSON stringify x 然后 y 将返回 key1 xxx 有什么办法可以通过 stringi
  • 在 Matlab 中创建二进制矩阵,报告数量不断增加

    我希望你建议编写一个创建二进制矩阵的 Matlab 代码A尺寸的31x5这样 第一行A is 1 1 1 1 1 从2号到6号A我们有1每行仅一次 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0
  • 如何更改android模拟器的日期?

    我需要更改模拟器的日期 你该怎么做 我尝试了开发设置 但他们不让我编辑它 我刚刚尝试过 像在任何其他 Android 设备上一样更改它 打开正常设置 不是开发 并转到日期和时间 取消选中 自动日期和时间 并在下面设置所需的日期
  • 运行时的 Java 编译器

    在我当前的项目中 我需要在运行时编译java代码 在后台处理用户的输入 这与类路径中的tools jar 配合得很好 但是 并非我的程序的所有用户都在其系统上安装了 JDK 其中一些只有 JRE 在这种情况下 运行时没有可用的 java 编
  • 使用Holoviews,如何设置标题?

    我一直在尝试在使用 Holoviews 和 Bokeh 时设置标题 我将 3 个图相互叠加 代码如下所示 opts Curve width 900 height 400 show grid True tools hover finalize
  • 如何删除 d3.behavior.drag().on("drag",...) 事件处理程序[重复]

    这个问题在这里已经有答案了 我将以下内容附加到 svg 元素 var dragger d3 behavior drag origin function d return d on drag this move on dragend drop
  • 选择要从中选择的表,取决于已给定表的列值

    为了我的目的 我必须选择一个表来根据已给定表的列值选择列 首先 我考虑了 CASE 构造 如果 sqlite 可以实现的话 SELECT FROM CASE IF myTable column1 value1 THEN SELECT FRO
  • 如何获取可执行文件的版本?

    萨尔维特 我正在编写一个 vb net 程序来更新我的应用程序的自述文件 我想从其他编译的应用程序中提取版本号 我想从可执行文件中读取版本号 而不是从其未编译的资源中读取版本号 如何在 vb net 中执行此操作而不使用像 reshacke
  • 除了锁定的对象之外,我还可以将对象更改保存到另一个 TR 中吗?

    当我尝试切换到报告源的编辑模式时 会出现一个弹出窗口告诉我 将为用户XXX的以下请求创建一个新任务 还提出了运输请求 但是 我不想在此请求中保存我的更改 而是在另一个现有请求中保存更改 我不知道我的系统中正在实施任何版本控制系统 也不知道如
  • iOS ClipsToBounds YES 和 Shadow?

    我有一个浮动的 UITableView 有圆角和设定的高度 但我也想添加阴影 但我的问题是我需要clipsToBounds打开 这样我的单元格就不会超出浮动的 UITableView 是否有办法在为 UITableView 保持 Clips
  • 使用 androidx DialogFragment 创建 AlertDialog 时按钮样式错误

    这是我的根风格
  • Firefox 3 书签中的 Http Auth

    我正在尝试创建一个书签 用于将 del icio us 书签发布到单独的帐户 我从命令行测试了它 例如 wget O no check certificate https seconduser email protected cdn cgi
  • 如何将 Jaeger 与 Spring WebFlux 结合使用?

    我们正在尝试与 Webflux 进行反应 我们将 Jaegar 与 Istio 结合使用来实现检测目的 Jaeger 很好地理解 Spring MVC 端点 但似乎根本不适用于 WebFlux 我正在寻找让我的 webflux 端点出现在
  • 将变量传递给 R 中的 WinBugs 模型

    我正在使用 R2WinBugs 包 我想将之前在 R 脚本中计算的两个参数传递给模型函数 c0yy lt 0 1 syy lt 0 0001 Model model lt function c0yy syy Likelihood for i
  • 如何使用 rspec 测试路由约束

    我正在开发一个主要用作 API 的应用程序 除了一些次要视图 例如会话 注册 这将是 标准 我喜欢最终确定的方法Railscast 350 API 版本控制 http railscasts com episodes 350 rest api
  • JPA/Hibernate 选择查询返回重复记录

    我有一个表 例如 Instrument 其中包含 ID State 和 User ID 作为列 所以我有这个 JPA 查询来返回所有具有匹配的仪器记录 用户身份 query manager createQuery SELECT instru
  • 在 matplotlib 轴上设置科学限制后调整指数文本

    目前 如果我将 matplotlib y 轴刻度标签设置为科学模式 它会在表单 y 轴顶部给出一个指数1e 5 我想调整这个来阅读r mathregular 10 5 这样就可以很好地打印出来 这是我的示例代码 Create a figur