设置绘图的自动缩放限制,以便在所有点周围都有缓冲区

发布于 2024-11-09 14:44:43 字数 1321 浏览 0 评论 0原文

我想在 matplotlib 中使用 pyplot 绘制一组点,但没有任何点位于轴的边缘。自动缩放(或其他东西)设置xlimylim,使得第一个和最后一个点通常位于x = xminxmax 在某些情况下难以阅读。

这在 loglog()semilog() 绘图中更常见,因为自动缩放需要 xminxmax准确地说是十的幂,但如果我的数据仅包含三个点,例如在 xdata = [10**2,10**3,10**4] 处,那么第一个和最后一个点将位于地块的边界上。

尝试的解决方法

这是我的解决方案,在图表的任一侧添加 10% 的缓冲区。但有没有一种方法可以更优雅或更自动地完成此操作?

from numpy import array, log10
from matplotlib.pyplot import *

xdata = array([10**2,10**3,10**4])
ydata = xdata**2

figure()
loglog(xdata,ydata,'.')
xmin,xmax = xlim()
xbuff = 0.1*log10(xmax/xmin)
xlim(xmin*10**(-xbuff),xmax*10**(xbuff))

我希望有一个单行或两行的解决方案,每当我制作这样的图时,我都可以轻松使用它。

线性图

为了清楚地说明我在解决方法中所做的事情,我应该在线性空间(而不是对数空间)中添加一个示例:

plot(xdata,ydata)
xmin,xmax = xlim()
xbuff = 0.1*(xmax-xmin)
xlim(xmin-xbuff,xmax+xbuff))

这与前面的示例相同,但针对的是线性轴。

限制太大

一个相关的问题是有时限制太大。假设我的数据类似于 ydata = xdata**0.25,因此范围内的方差远小于十年,但恰好以 10**1 结束。然后,自动缩放 ylim10**010**1,尽管数据仅位于绘图的顶部部分。使用上面的解决方法,我可以增加ymax,以便第三点完全在限制内,但我不知道如何增加ymin这样我的图下部的空白就会减少。即,重点是我并不总是想分散我的限制,而是只想在我的所有点周围有一些恒定(或成比例)的缓冲区。

I would like to plot a set of points using pyplot in matplotlib but have none of the points be on the edge of my axes. The autoscale (or something) sets the xlim and ylim such that often the first and last points lie at x = xmin or xmax making it difficult to read in some situations.

This is more often problematic with loglog() or semilog() plots because the autoscale would like xmin and xmax to be exact powers of ten, but if my data contains only three points, e.g. at xdata = [10**2,10**3,10**4] then the first and last points will lie on the border of the plot.

Attempted Workaround

This is my solution to add a 10% buffer to either side of the graph. But is there a way to do this more elegantly or automatically?

from numpy import array, log10
from matplotlib.pyplot import *

xdata = array([10**2,10**3,10**4])
ydata = xdata**2

figure()
loglog(xdata,ydata,'.')
xmin,xmax = xlim()
xbuff = 0.1*log10(xmax/xmin)
xlim(xmin*10**(-xbuff),xmax*10**(xbuff))

I am hoping for a one- or two-line solution that I can easily use whenever I make a plot like this.

Linear Plot

To make clear what I'm doing in my workaround, I should add an example in linear space (instead of log space):

plot(xdata,ydata)
xmin,xmax = xlim()
xbuff = 0.1*(xmax-xmin)
xlim(xmin-xbuff,xmax+xbuff))

which is identical to the previous example but for a linear axis.

Limits too large

A related problem is that sometimes the limits are too large. Say my data is something like ydata = xdata**0.25 so that the variance in the range is much less than a decade but ends at exactly 10**1. Then, the autoscale ylim are 10**0 to 10**1 though the data are only in the top portion of the plot. Using my workaround above, I can increase ymax so that the third point is fully within the limits but I don't know how to increase ymin so that there is less whitespace at the lower portion of my plot. i.e., the point is that I don't always want to spread my limits apart but would just like to have some constant (or proportional) buffer around all my points.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

拿命拼未来 2024-11-16 14:44:43

@askewchan 我刚刚成功地实现了如何通过编辑 matplotlibrc 配置文件并直接从终端运行 python 来更改 matplotlib 设置。 还不知道原因,但是当我从spyder3(我的IDE)运行python时,matplotlibrc无法工作。只需按照此处的步骤操作matplotlib.org/users/customizing.html

1) 解决方案一(所有绘图的默认值)

尝试将其放入 matplotlibrc 中,您将看到缓冲区增加:

axes.xmargin        : 0.1  # x margin.  See `axes.Axes.margins`
axes.ymargin        : 0.1  # y margin See `axes.Axes.margins`

值必须在 0 和 1 之间。

观察: 由于错误,比例尚未正常工作。它将针对 matplotlib 1.5 进行修复(我的版本是 1.4.3...)。更多信息:

2)解决方案二(分别针对代码内的每个图)

还有边距功能(用于直接放入代码中)。示例:

import numpy as np
from matplotlib import pyplot as plt 
t = np.linspace(-6,6,1000)
plt.plot(t,np.sin(t))
plt.margins(x=0.1, y=0.1)
plt.savefig('plot.png')

观测: 这里比例起作用(0.1 将在 x 范围和 y 范围之前和之后增加 10% 的缓冲区)。

@askewchan I just succesfully achieved how to change matplotlib settings by editing matplotlibrc configuration file and running python directly from terminal. Don't know the reason yet, but matplotlibrc is not working when I run python from spyder3 (my IDE). Just follow steps here matplotlib.org/users/customizing.html.

1) Solution one (default for all plots)

Try put this in matplotlibrc and you will see the buffer increase:

axes.xmargin        : 0.1  # x margin.  See `axes.Axes.margins`
axes.ymargin        : 0.1  # y margin See `axes.Axes.margins`

Values must be between 0 and 1.

Obs.: Due to bugs, scale is not correctly working yet. It'll be fixed for matplotlib 1.5 (mine is 1.4.3 yet...). More info:

2) Solution two (individually for each plot inside the code)

There is also the margins function (for put directly in the code). Example:

import numpy as np
from matplotlib import pyplot as plt 
t = np.linspace(-6,6,1000)
plt.plot(t,np.sin(t))
plt.margins(x=0.1, y=0.1)
plt.savefig('plot.png')

Obs.: Here scale is working (0.1 will increase 10% of buffer before and after x-range and y-range).

薄凉少年不暖心 2024-11-16 14:44:43

向 matplotlib- 提出了 类似问题今年早些时候的用户名单。最有前途的解决方案涉及实现定位器(基于 MaxNLocator< /a> 在这种情况下)覆盖 MaxNLocator.view_limits。

A similar question was posed to the matplotlib-users list earlier this year. The most promising solution involves implementing a Locator (based on MaxNLocator in this case) to override MaxNLocator.view_limits.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文