使用 Python 2.7 和 matplotlib,如何使用两种不同的样式创建二维线?

Using Python 2.7 and matplotlib, how do I create a 2D Line using two different styles?

在个人项目上绘制两条线,前两个 x 轴标记为虚线 (ls='--'),然后是实线...考虑编写教程,因为我查不到这方面的资料。无论如何,我被难住了的诀窍是计算前两个 x 轴标记使用多少点来制作线,这样我就可以正确地关闭到该点的实线。我正在使用 Line.set_dashes() 方法关闭实线,我正在制作一个单独的(非连接的)副本并将线型设置为破折号。这会导致线条绘制在彼此之上,并且实体在打开时优先。但是,Line.set_dashes() 将 "points" 作为参数。我想出了在哪里,但正如你所见,第二条线有不同的角度,因此长度不同,所以这个点沿着这条线更远。也许有更好的方法将线条设置为两种样式?

这是一个示例图 --> https://flic.kr/p/rin6Z5

r = getPostData(wall)

if len(newTimes) < LIMIT:
    LIMIT = len(newTimes)
yLim = int(round(max(r['Likes'].max(), r['Shares'].max()) * 1.2))
xLim = LIMIT
L1A = plt.Line2D(range(LIMIT), r['Likes'], color='b', ls='--')
L1B = plt.Line2D(range(LIMIT), r['Likes'], label='Likes', color='b')
L2A = plt.Line2D(range(LIMIT), r['Shares'], color='r', ls='--')
L2B = plt.Line2D(range(LIMIT), r['Shares'], label='Shares', color='r')
LNull = plt.Line2D(range(LIMIT), r['Shares'], ls='--', label='Recent Data\n(Early collection)', color='k')
dashes = [1,84,7000,1]
dashesNull=[1,7000]
fig = plt.figure()
ax = fig.add_subplot(111, ylim=(0,yLim), xlim=(0,xLim))
ax.add_line(L1A)
ax.add_line(L1B)
ax.add_line(L2A)
ax.add_line(L2B)
ax.add_line(LNull)
ax.legend(bbox_to_anchor=(1.5,1))
L1B.set_dashes(dashes)
L2B.set_dashes(dashes)
LNull.set_dashes(dashesNull)

我会给你自己写一个辅助函数,比如:

import numpy as np
import matplotlib.pyplot as plt

def split_plot(ax, x, y, low, high, inner_style, outer_style):
    """
    Split styling of line based on the x-value

    Parameters
    ----------
    x, y : ndarray
        Data, must be same length

    low, high : float
        The low and high threshold values, points for `low < x < high` are
        styled using `inner_style` and points for `x < low or x > high` are
        styled using `outer_style`

    inner_style, outer_style : dict
        Dictionary of styles that can be passed to `ax.plot`

    Returns
    -------
    lower, mid, upper : Line2D
        The artists for the lower, midddle, and upper ranges

    vline_low, vline_hi : Line2D
        Vertical lines at the thresholds

    hspan : Patch
        Patch over middle region
    """

    low_mask = x < low
    high_mask = x > high
    mid_mask = ~np.logical_or(low_mask, high_mask)

    low_mask[1:] |= low_mask[:-1]
    high_mask[:-1] |= high_mask[1:]

    lower, = ax.plot(x[low_mask], y[low_mask], **outer_style)
    mid, = ax.plot(x[mid_mask], y[mid_mask], **inner_style)
    upper, = ax.plot(x[high_mask], y[high_mask], **outer_style)

    # add vertical lines
    vline_low = ax.axvline(low, color='k', ls='--')
    vline_high = ax.axvline(high,  color='k', ls='--')

    hspan = ax.axvspan(low, high, color='b', alpha=.25)

    return lower, mid, upper, vline_low, vline_high, hspan

这显然可以概括为垂直线和跨度采用3个线型字典和样式信息。你像这样使用它:

inner_style = {'color': 'r', 'lw': 5, 'ls':'--'}
outer_style = {'color': 'r', 'lw': 1, 'ls':'-'}

x = np.linspace(0, 2*np.pi, 1024)
y = np.sin(x)

low = np.pi / 2
high = 3*np.pi / 2

fig, ax = plt.subplots()

lower, mid, upper, vl_low, vl_high, hsp = split_plot(ax, x, y, low, high, inner_style, outer_style)
plt.show()

我也是这么想的,反正现在生成的代码是...

def splitLine(ax, x, y, splitNum, style1, style2):
    '''Creates a two styled line given;
    ax = an axis
    x  = an array of x coordinates for 2D Line
    y  = an array of y coordinates for 2D Line
    splitNum = index number to split Line by x tick
    style1 = dictionary for left part of Line
    style2 = dictionary for right part of Line
    '''
    split = x[splitNum]
    low_mask = x <= split
    upper_mask = x >= split

    lower, = ax.plot(x[low_mask], y[low_mask], **style1)
    upper, = ax.plot(x[upper_mask], y[upper_mask], **style2)

    return lower, upper


r = getPostData(wall)



earlyLike  = {'color': 'r', 'lw': 1, 'ls': '--'}
agedLike   = {'color': 'r', 'lw': 2, 'ls': '-', 'label': 'Likes'}
earlyShare = {'color': 'b', 'lw': 1, 'ls': '--'}
agedShare  = {'color': 'b', 'lw': 2, 'ls': '-', 'label': 'Shares'}

fig, ax = plt.subplots()

splitLine(ax, np.array(range(LIMIT)), np.array(r['Likes']), 1, earlyLike, agedLike)
splitLine(ax, np.array(range(LIMIT)), np.array(r['Shares']), 1, earlyShare, agedShare)