Python 如何使垂直线接触图表的边界?

Python 如何使垂直线接触图表的边界?,python,pandas,matplotlib,Python,Pandas,Matplotlib,我希望使用ax.vline创建的垂直线能够接触图表的上下限,方式与axvline相同 考虑这个简单的例子: import pandas as pd import matplotlib.pyplot as plt df = pd.DataFrame({'time' : [pd.to_datetime('2016-01-02'), pd.to_datetime('2016-01-03'), pd.to_datetime('2016-01-04')], 'val

我希望使用
ax.vline
创建的垂直线能够接触图表的上下限,方式与
axvline
相同

考虑这个简单的例子:

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame({'time' : [pd.to_datetime('2016-01-02'), pd.to_datetime('2016-01-03'), pd.to_datetime('2016-01-04')],
                   'value1' : [1, 2, 3],
                   'value2' : [10, 20, 30]})

df.set_index('time', inplace = True)

df
Out[95]: 
            value1  value2
time                      
2016-01-02       1      10
2016-01-03       2      20
2016-01-04       3      30
现在的图表是:

fig, ax = plt.subplots(figsize=(30, 15))

ax.plot(df.index, df["value1"], color = 'black')

ax2 = ax.twinx()
ax2.plot(df.index, df["value2"], color = 'red')

#axvline stretches nicely
ax.axvline( pd.to_datetime('2016-01-04'), color = 'red',  alpha = 1,  linestyle = '--')

#vlines stops before touching the upper and lower boundaries
ymin, ymax = ax2.get_ylim()
ax.vlines([pd.to_datetime('2016-01-02'), pd.to_datetime('2016-01-03')],  ymin = ymin, ymax = ymax, color = 'blue', linestyle = '-')
给出:

你可以看到那些蓝色的线仍然在空中,而漂亮的红色垂直线完全伸展。我怎样才能做到这一点


谢谢

您需要
设置_ylim
,这样在绘制
vline
时轴不会改变。在
ax.vlines(…)
行之前添加
ax.set_ylim(ymin,ymax)

一件小事是,您可能希望在
ax2
上绘制
vline
,因为您使用了
ax2
中的
ymin,ymax
。因此,我更新了您的代码,如下所示:

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame({'time': [pd.to_datetime('2016-01-02'),
                            pd.to_datetime('2016-01-03'),
                            pd.to_datetime('2016-01-04')],
                   'value1': [1, 2, 3],
                   'value2': [10, 20, 30]})
df.set_index('time', inplace=True)

fig, ax = plt.subplots(figsize=(30, 15))
ax.plot(df.index, df["value1"], color='black')
ax2 = ax.twinx()
ax2.plot(df.index, df["value2"], color='red')

#axvline stretches nicely
ax.axvline(pd.to_datetime('2016-01-04'), color = 'red',
           alpha = 1,  linestyle = '--')

#vlines stretches nicely
ymin, ymax = ax2.get_ylim()
ax2.set_ylim(ymin, ymax)
ax2.vlines([pd.to_datetime('2016-01-02'), pd.to_datetime('2016-01-03')],
           ymin=ymin, ymax=ymax, color='blue', linestyle='-')

plt.show()

您需要
设置ylim
,以便在绘制
vline
时轴不会改变。在
ax.vlines(…)
行之前添加
ax.set_ylim(ymin,ymax)

一件小事是,您可能希望在
ax2
上绘制
vline
,因为您使用了
ax2
中的
ymin,ymax
。因此,我更新了您的代码,如下所示:

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame({'time': [pd.to_datetime('2016-01-02'),
                            pd.to_datetime('2016-01-03'),
                            pd.to_datetime('2016-01-04')],
                   'value1': [1, 2, 3],
                   'value2': [10, 20, 30]})
df.set_index('time', inplace=True)

fig, ax = plt.subplots(figsize=(30, 15))
ax.plot(df.index, df["value1"], color='black')
ax2 = ax.twinx()
ax2.plot(df.index, df["value2"], color='red')

#axvline stretches nicely
ax.axvline(pd.to_datetime('2016-01-04'), color = 'red',
           alpha = 1,  linestyle = '--')

#vlines stretches nicely
ymin, ymax = ax2.get_ylim()
ax2.set_ylim(ymin, ymax)
ax2.vlines([pd.to_datetime('2016-01-02'), pd.to_datetime('2016-01-03')],
           ymin=ymin, ymax=ymax, color='blue', linestyle='-')

plt.show()

您可能想做的是使蓝线独立于y方向的数据。这可以使用
xaxis_变换
并将ymin和ymax分别设置为0和1来完成

ax.vlines([pd.to_datetime('2016-01-02'), pd.to_datetime('2016-01-03')],  
           ymin = 0, ymax = 1, color = 'blue', linestyle = '-', 
           transform=ax.get_xaxis_transform())

因此,我们模拟了与axvline
使用的行为完全相同的行为,即对x值使用数据变换,对y值使用轴变换。轴坐标在轴内的范围从0到1,因此使用这些值将始终使线从y轴的一端开始并到达另一端,无论其数据范围如何。

您可能要做的是使蓝线独立于y方向的数据。这可以使用
xaxis_变换
并将ymin和ymax分别设置为0和1来完成

ax.vlines([pd.to_datetime('2016-01-02'), pd.to_datetime('2016-01-03')],  
           ymin = 0, ymax = 1, color = 'blue', linestyle = '-', 
           transform=ax.get_xaxis_transform())

因此,我们模拟了与axvline
使用的行为完全相同的行为,即对x值使用数据变换,对y值使用轴变换。轴坐标在轴内的范围从0到1,因此使用这些值将始终使线从y轴的一端开始并到达另一端,无论其数据范围如何。

这是否也适用于双轴?它在本例中有效吗?是的,它在ax2上有效。更新了我的答案。请查收。谢谢。实际上它不起作用,因为黑线现在从图表中消失了@ℕʘʘḆḽḘ 已上载ax2上所有内容的新图表。黑线与红线重叠。这就是为什么我怀疑您想在
ax2
上绘制
vline
而不是
ax
,因为
ax.set_ylim(ymin,ymax)
会隐藏黑线。这对双轴也适用吗?它在本例中有效吗?是的,它在ax2上有效。更新了我的答案。请查收。谢谢。实际上它不起作用,因为黑线现在从图表中消失了@ℕʘʘḆḽḘ 已上载ax2上所有内容的新图表。黑线与红线重叠。这就是为什么我怀疑你想在
ax2
上绘制
vline
而不是
ax
,因为
ax.set_ylim(ymin,ymax)
会隐藏黑线。另一个疯狂的matplotlib魔术我添加了一些解释。基本上,这与axvline相同,因为它使用轴坐标表示垂直方向。@ImportanceOfBeingErnest伟大的答案!我对这个
转换
概念感兴趣。我在哪里可以找到这方面的文档?我可以问一下为什么它在这里使用xaxis而不是yaxis变换吗?这是因为它们是x轴网格线吗?@Y.Luo x轴是沿着其范围具有数据的轴,并且在轴坐标中位于Y=0处。这也是这里所用的。这里有一个可以涵盖你需要知道的大部分内容的例子。另一个疯狂的matplotlib魔术我补充了一点解释。基本上,这与axvline相同,因为它使用轴坐标表示垂直方向。@ImportanceOfBeingErnest伟大的答案!我对这个
转换
概念感兴趣。我在哪里可以找到这方面的文档?我可以问一下为什么它在这里使用xaxis而不是yaxis变换吗?这是因为它们是x轴网格线吗?@Y.Luo x轴是沿着其范围具有数据的轴,并且在轴坐标中位于Y=0处。这也是这里所用的。有一个可以涵盖你需要知道的大部分内容的方法。