将一个或两个轴都居中以围绕特定绘图中心“视图”。

huangapple go评论85阅读模式
英文:

Center one or both axis to center the "view" around a specific plot

问题

让我们说**点(10, 50)**将我的二维坐标系绘图分成四个部分:

  • 左上,右上
  • 左下,右下

这个点是固定的,我提前知道它的位置。

任务:始终将这个点保持在matplotlib显示的坐标系的中间。

当然,我可以通过例如设置以下内容来实现这一点:

axs.set_xlim(0, 20)
axs.set_ylim(0, 100)

这样可以完美地将提到的点居中在图形的中间。这种方法的问题在于,我事先不知道要在这个图中可视化的动态散点数据。

有时可能是这样的:

x_data = (2, 5, 15)
y_data = (25, 30, 75)

这将适用于我之前设置的xlimylim,但有时数据可能是这样的:

x_data = (-10, 0, 20)
y_data = (-2, 101, 205)

这些数据不会显示,因为它们在设置的xlimylim之外。

**问题:**我是否可以保持轴的默认动态扩展,以便包含我的所有数据点,并且仍然以某种方式将点居中在图形的“中间”?

不同的表述:我是否可以指定轴的中心位置,而不指定其最小值和最大值,并且仍然保持自动缩放,以便“包括每个点”?

英文:

Let's say the point (10, 50) divides my plot of a 2d coordinate system in four sections:

  • top left, top right
  • bottom left, bottom right

This point is fixed and I know its location in advance.

Task: Always keep this point in the middle of the by matplotlib displayed coordinate system.

Sure I can achieve this by for example setting

axs.set_xlim(0, 20)
axs.set_ylim(0, 100)

This perfectly centers mentioned point in the middle of the graph. The problem with this approach is, that I do not know in advance about my dynamic scatter data that I also want to visualize within this plot.

Sometimes it might be

x_data = (2, 5, 15)
y_data = (25, 30, 75)

This would work with my previously set xlim and ylim but sometimes the data might be:

x_data = (-10, 0, 20)
y_data = (-2, 101, 205)

This data would not show up because it is outside of set xlim and ylim.

Question: Can I keep the default dynamic expanding of the axis so every point of my data is included and still somehow center the point in "the middle" of the graph?

Different phrasing: Can I specify the center of an axis without specifying its min and max and still keep the auto scaling so "every point" that is to scatter is included?

答案1

得分: 1

一个用户的评论中:

> 我的问题更多是:“我能在不指定xlim和ylim的情况下居中轴吗?”

不能。

英文:

From an OP's comment

> My question was more: "Can I center the axis without specifying xlim and ylim?"

No.

答案2

得分: 0

我会使用类似这样的代码(对于 x 轴):

if x_data:
    left_span, right_span = center_x - min(x_data), max(x_data) - center_x
    half_x_span = max(left_span, right_span)
    if half_x_span > 0:
        axs.set_xlim(center_x - half_x_span, center_x + half_x_span)
英文:

I would use something like (for x axis):

if x_data:
    left_span, right_span = center_x - min(x_data), max(x_data) - center_x
    half_x_span = max(left_span, right_span)
    if half_x_span > 0:
        axs.set_xlim(center_x - half_x_span, center_x + half_x_span)

答案3

得分: 0

    Smin                       Smax
  |---+---------------|----------+-------|
 C-L                 C                  C+L

从前面的图中,我们有

C+L ≥ Smax ⇒ L ≥ Smax-C
Smin ≥ C-L ⇒ L ≥ C-Smin

最后

L = max(Smax-C, C-Smin)

翻译到Matplotlib的上下文中:

def limits(c, mnmx):
    mn, mx = mnmx
    L = max(mx-c, c-mn)
    return(c-L, c+L)

xc, yc = 10, 50
# 绘制你的数据
ax.set_xlim(limits(xc, ax.get_xlim()))
ax.set_ylim(limits(yc, ax.get_ylim()))

以下是一个示例

将一个或两个轴都居中以围绕特定绘图中心“视图”。

import matplotlib.pyplot as plt

def limits(c, mnmx):
    mn, mx = mnmx
    L = max(mx-c, c-mn)
    return (c-L, c+L)

def plot_example(ax, xmn_xmx):
    y = [50, 50]
    ax.scatter(xmn_xmx, y)
    ax.scatter(10, 50)
    ax.set_xlim(limits(10, ax.get_xlim()))

fig, axes = plt.subplots(3, figsize=(6, 6), constrained_layout=True)
for ax, xmn_xmx in zip(axes, ((-3, -2), (12, 15), (-20, 100))):
    plot_example(ax, xmn_xmx)
plt.show()

<details>
<summary>英文:</summary>

```none
    Smin                       Smax
  |---+---------------|----------+-------|
 C-L                 C                  C+L

From the previous figure, we have

C+L ≥ Smax ⇒ L ≥ Smax-C
Smin ≥ C-L ⇒ L ≥ C-Smin

and finally

L = max(Smax-C, C-Smin)

Translated into the context of Matplotlib

def limits(c, mnmx):
    mn, mx = mnmx
    L = max(mx-c, c-mn)
    return(c-L, c+L)

xc, yc = 10, 50
# plot your data
ax.set_xlim(limits(xc, ax.get_xlim())
ax.set_ylim(limits(yc, ax.get_ylim())

An example follows

将一个或两个轴都居中以围绕特定绘图中心“视图”。

In [22]: import matplotlib.pyplot as plt

In [23]: def limits(c, mnmx):
    ...:     mn, mx = mnmx
    ...:     L = max(mx-c, c-mn)
    ...:     return (c-L, c+L)

In [24]: def plot_example (ax, xmn_xmx):
    ...:     y = [50, 50]
    ...:     ax.scatter(xmn_xmx, y)
    ...:     ax.scatter(10, 50)
    ...:     ax.set_xlim(limits(10, ax.get_xlim()))

In [25]: fig, axes = plt.subplots(3, figsize=(6, 6), layout=&#39;constrained&#39;)
    ...: for ax, xmn_xmx in zip(axes, ((-3, -2), (12, 15), (-20, 100))):
    ...:     plot_example(ax, xmn_xmx)
    ...: plt.show()

huangapple
  • 本文由 发表于 2023年6月1日 17:37:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/76380541.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定