用虚线替换部分图

时间:2018-01-15 09:21:44

标签: 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.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()

这是原始情节

original plot

修改情节:

modified plot

我编写的代码有效(它产生了所需的输出),但它实际上在我(更大)的数据集上运行时效率很低并且需要很长时间。有没有更聪明的方法来做这件事?

3 个答案:

答案 0 :(得分:2)

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

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()

结果如下:

enter image description here

但请注意,如果第一个值为-1,则会失败,因为您的问题没有明确定义(之前没有要复制的值)。希望这会有所帮助。

答案 1 :(得分:2)

你可以在没有循环的情况下实现类似的东西:

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()

enter image description here

您还可以通过为线条选择不同的颜色来突出显示负区域: enter image description here

我的答案基于2017年7月的一篇好文章。后者也解决了第一个元素是NaN或者你的情况是负数的情况: Dotted lines instead of a missing value in matplotlib

答案 2 :(得分:0)

不是太优雅,但是这里有一些不使用我想出的循环(根据上面的答案)有效。 @KRKirov和@ThomasKühn,谢谢你的回答,我真的很感激他们

    var pdf = new jsPDF('p', 'pt', 'letter');
    pdf.addFileToVFS('CustomFont.tff', 'base64 of .tff file');
    pdf.addFont('CustomFont.tff', 'CustomFont', 'normal');
    pdf.setFont('CustomFont');
    var source = $('#pdf')[0];
    var margins = {
        top: 50,
        bottom: 60,
        left: 40,
        width: 520
    };
    pdf.fromHTML(
        source,
        margins.left,
        margins.top, {
            'width': margins.width, 
            'elementHandlers': specialElementHandlers
        },
        function (dispose) {
            pdf.save('Test.pdf');
        }, margins);
相关问题