转换坐标Seaborn / Matplotlib

时间:2019-04-24 09:18:11

标签: python pandas matplotlib seaborn

如何将图的坐标转换为下图所示的X和Y值的坐标,其中左下角为0,0,右上角为1,1?

我要实现的是在图形顶部绘制标签A,V,U,I和M,大约在标签“其他信息”所在的高度,但保持X位置。它将改变回归图中的点数,因此无法进行硬编码。

我尝试使用https://matplotlib.org/tutorials/advanced/transforms_tutorial.html中所述的transData和transAxes,但无法转换为将Y坐标0.8转换为约26的方式。

以其他方式进行转换也可以,但是随后需要将X坐标转换为2.5到0.2。 enter image description here

import seaborn as sns
import numpy as np
import pandas as pd

status = ['A', 'V', 'U', 'I', 'M']
x_array = np.array([2, 4, 6, 8, 10])
y_array = np.array([5, 9, 15, 21, 27])
x, y = pd.Series(x_array, name="Values X"), pd.Series(y_array, name="Values Y")
ax_regplot = sns.regplot(x=x, y=y, scatter=True)
ax_regplot.set_title("My plot")
ax_regplot.figure.text(0.2, 0.8, "Additional Information", fontsize=8)

for i in range(len(x_array)):
    x_coordinate = x_array[i]
    y_coordinate = y_array[i]
    ax_regplot.text(x_coordinate, y_coordinate, status[i])

ax_regplot.figure.savefig("my_plot.png")

2 个答案:

答案 0 :(得分:1)

您确实可以在这里使用多个坐标系。想法是,文本元素的y坐标以轴为单位(在坐标轴的整个范围内,范围从0到1),而x坐标以数据单位为单位。例如,将在(2, 0.8)上设置字母“ A”,其中2为数据单位,而0.8轴单位。这种系统称为“混合坐标系”。我们可以手动创建此类混合系统,也可以使用xaxis转换,无论如何都使用此精确系统。

另外使用annotate代替text可以在文本中的点上添加小的偏移量。这可以用于使标题文本和字母具有相同的轴坐标,但仍使它们相对于彼此移动一些点。

import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np

status = ['A', 'V', 'U', 'I', 'M']
x = np.array([2, 4, 6, 8, 10])
y = np.array([5, 9, 15, 21, 27])


ax = sns.regplot(x=x, y=y, scatter=True)
ax.set_title("My plot")


ax.annotate("Additional Information", xy=(0,0.8), xytext=(20, 10),
                   xycoords="axes fraction", textcoords="offset points",
                   fontsize=8)

for i in range(len(x)):
    ax.annotate(status[i], xy=(x[i], 0.8), xytext=(0, -2),
                   xycoords=ax.get_xaxis_transform(), textcoords="offset points",
                   fontsize=10, ha="center")

plt.show()

enter image description here

答案 1 :(得分:0)

您可以简单地使用Y来获得get_ylim()的最大值,并根据需要缩放它的最大值(在下面的示例中,我取最大值的0.8)。
get_ylim()返回带有轴上下限的元组,我们通过索引[1]选择上端。

status = ['A', 'V', 'U', 'I', 'M']
x_array = np.array([2, 4, 6, 8, 10])
y_array = np.array([5, 9, 15, 21, 27])
x, y = pd.Series(x_array, name="Values X"), pd.Series(y_array, name="Values Y")
ax_regplot = sns.regplot(x=x, y=y, scatter=True)
ax_regplot.set_title("My plot")
ax_regplot.figure.text(0.2, 0.8, "Additional Information", fontsize=8)

我们只需要更改循环的最后一行:

for i in range(len(x_array)):
    x_coordinate = x_array[i]
    y_coordinate = y_array[i]
    ax_regplot.text(x_coordinate, 0.8*ax_regplot.get_ylim()[1], status[i])

编辑:

在@Rob的评论之后,您可以将答案概括为:

ylim=ax_regplot.get_ylim()
for i in range(len(x_array)):
    x_coordinate = x_array[i]
    y_coordinate = y_array[i]
    ax_regplot.text(x_coordinate, ylim[0] + .8 * (ylim[1] - ylim[0]), status[i])

example