Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 用虚线替换部分绘图_Python_Numpy_Matplotlib_Plot - Fatal编程技术网

Python 用虚线替换部分绘图

Python 用虚线替换部分绘图,python,numpy,matplotlib,plot,Python,Numpy,Matplotlib,Plot,我想用一条从上一点开始的虚线(参见下面的图)替换我的部分图,其中函数下降到“-1” 以下是我编写的一些代码及其输出: import numpy as np import matplotlib.pyplot as plt y = [5,6,8,3,5,7,3,6,-1,3,8,5] plt.plot(np.linspace(1,12,12),y,'r-o') plt.show() for i in range(1,len(y)): if y[i]!=-1: plt.p

我想用一条从上一点开始的虚线(参见下面的图)替换我的部分图,其中函数下降到“-1”

以下是我编写的一些代码及其输出:

import numpy as np

import matplotlib.pyplot as plt
y = [5,6,8,3,5,7,3,6,-1,3,8,5]

plt.plot(np.linspace(1,12,12),y,'r-o')
plt.show()

for i in range(1,len(y)):
    if y[i]!=-1:
        plt.plot(np.linspace(i-1,i,2),y[i-1:i+1],'r-o')
    else:
        y[i]=y[i-1]
        plt.plot(np.linspace(i-1,i,2),y[i-1:i+1],'r--o')
plt.ylim(-1,9)
plt.show()
这是原图

修改图:


我编写的代码是有效的(它会产生所需的输出),但当我在我的(更大的)数据集上实际运行它时,效率很低,而且需要很长时间。有没有更聪明的方法可以做到这一点?

我会使用
numpy
功能将直线切割成线段,然后分别绘制所有实线和虚线。在下面的示例中,我向您的数据中添加了两个额外的
-1
s,以确保这是通用的

import numpy as np
import matplotlib.pyplot as plt

Y = np.array([5,6,-1,-1, 8,3,5,7,3,6,-1,3,8,5])
X = np.arange(len(Y))

idxs =  np.where(Y==-1)[0]

sub_y = np.split(Y,idxs)
sub_x = np.split(X,idxs)

fig, ax = plt.subplots()

##replacing -1 values and plotting dotted lines
for i in range(1,len(sub_y)):
    val = sub_y[i-1][-1]
    sub_y[i][0] = val
    ax.plot([sub_x[i-1][-1], sub_x[i][0]], [val, val], 'r--')

##plotting rest
for x,y in zip(sub_x, sub_y):
    ax.plot(x, y, 'r-o')

plt.show()
结果如下所示:


但是,请注意,如果第一个值为
-1
,则此操作将失败,因为您的问题没有得到很好的定义(没有以前的值可从中复制)。希望这有帮助。

您可以在不使用循环的情况下实现类似的功能:

import pandas as pd
import matplotlib.pyplot as plt

# Create a data frame from the list
a = pd.DataFrame([5,6,-1,-1, 8,3,5,7,3,6,-1,3,8,5])

# Prepare a boolean mask
mask = a > 0

# New data frame with missing values filled with the last element of   
# the previous segment. Choose 'bfill' to use the first element of 
# the next segment.
a_masked = a[mask].fillna(method = 'ffill')

# Prepare the plot
fig, ax = plt.subplots()
line, = ax.plot(a_masked, ls = '--', lw = 1)
ax.plot(a[mask], color=line.get_color(), lw=1.5, marker = 'o')
plt.show()

您也可以通过为线条选择不同的颜色来突出显示负片区域:

我的答案基于2017年7月的一篇文章。后者还处理第一个元素为NaN或在您的情况下为负数时的情况:
不太优雅,但这里有一个不使用循环的东西,我根据上面的答案提出了这个方法@KRKirov和@Thomas Kühn,谢谢你的回答,我真的很感激他们

import pandas as pd
import matplotlib.pyplot as plt

# Create a data frame from the list
a = pd.DataFrame([5,6,-1,-1, 8,3,5,7,3,6,-1,3,8,5])

b=a.copy()
b[2]=b[0].shift(1,axis=0)
b[4]=(b[0]!=-1) & (b[2]==-1)
b[5]=b[4].shift(-1,axis=0)
b[0] = (b[5] | b[4])
c=b[0]
d=pd.DataFrame(c)

# Prepare a boolean mask
mask = a > 0

# New data frame with missing values filled with the last element of   
# the previous segment. Choose 'bfill' to use the first element of 
# the next segment.
a_masked = a[mask].fillna(method = 'ffill')

# Prepare the plot
fig, ax = plt.subplots()
line, = ax.plot(a_masked, 'b:o', lw = 1)
ax.plot(a[mask], color=line.get_color(), lw=1.5, marker = 'o')
ax.plot(a_masked[d], color=line.get_color(), lw=1.5, marker = 'o')
plt.show()

所以假设第一个值永远不会是-1?一个可能的想法是使用屏蔽数组,例如
y\u masked=np.ma.masked\u其中(y==1,y)
。绘制此图将丢失
-1
值,因此您仍然需要做一些工作来显示上一个值并添加虚线(可能只绘制遮罩的值)。谢谢!有没有办法让它完全一样?我更喜欢这个答案,因为它不使用循环。当有一长串-1时,上面的一个会变得非常慢。明白了吗?我会在几分钟后发布我自己的解决方案。我知道我已经接受了答案,但是有没有一种不使用循环的方法可以做到这一点?当我有一长串的工作清单时,这被证明是非常昂贵的-1s@Lupacante我认为另一个答案实际上是更好的解决方案。只要稍作调整,你就能得到你想要的东西。哦,如果你改变主意,接受另一个答案,那就没问题了:)谢谢!好的,我看看我能做什么