在matplotlib

时间:2016-06-08 16:34:36

标签: python matplotlib visualization

enter image description here

上图是一个很好的艺术作品,同时显示风速,风向和温度。详细说明:

  • X轴代表日期
  • Y轴显示风向(南部,西部等)
  • 该线的变体宽度代表通过时间序列的风速
  • 该线的变色代表大气温度

这个简单的图形可视化3个不同的属性而没有冗余。

所以,我真的想在matplotlib中重现类似的情节。

我现在的尝试

## Reference 1 http://stackoverflow.com/questions/19390895/matplotlib-plot-with-variable-line-width
## Reference 2 http://stackoverflow.com/questions/17240694/python-how-to-plot-one-line-in-different-colors

def plot_colourline(x,y,c):
    c = plt.cm.jet((c-np.min(c))/(np.max(c)-np.min(c)))
    lwidths=1+x[:-1]
    ax = plt.gca()
    for i in np.arange(len(x)-1):
        ax.plot([x[i],x[i+1]], [y[i],y[i+1]], c=c[i],linewidth = lwidths[i])# = lwidths[i])
    return

x=np.linspace(0,4*math.pi,100)
y=np.cos(x)
lwidths=1+x[:-1]

fig = plt.figure(1, figsize=(5,5))
ax  = fig.add_subplot(111)
plot_colourline(x,y,prop)

ax.set_xlim(0,4*math.pi)
ax.set_ylim(-1.1,1.1)

enter image description here

有人有更感兴趣的方法来实现这一目标吗?任何建议都会很感激!

2 个答案:

答案 0 :(得分:3)

使用灵感another question

一种选择是使用fill_between。但也许不是按照预期的方式。而不是用它来创建你的线,用它来掩盖不是线的一切。在其下方,您可以使用pcolormeshcontourf(例如)以任意方式映射颜色。

例如,看看这个例子:

import matplotlib.pyplot as plt
import numpy as np
from scipy.interpolate import interp1d

def windline(x,y,deviation,color):
    y1 = y-deviation/2
    y2 = y+deviation/2
    tol = (y2.max()-y1.min())*0.05
    X, Y = np.meshgrid(np.linspace(x.min(), x.max(), 100), np.linspace(y1.min()-tol, y2.max()+tol, 100))
    Z = X.copy()
    for i in range(Z.shape[0]):
        Z[i,:] = c

    #plt.pcolormesh(X, Y, Z)
    plt.contourf(X, Y, Z, cmap='seismic')

    plt.fill_between(x, y2, y2=np.ones(x.shape)*(y2.max()+tol), color='w')
    plt.fill_between(x, np.ones(x.shape) * (y1.min() - tol), y2=y1, color='w')
    plt.xlim(x.min(), x.max())
    plt.ylim(y1.min()-tol, y2.max()+tol)
    plt.show()

x = np.arange(100)
yo = np.random.randint(20, 60, 21)
y = interp1d(np.arange(0, 101, 5), yo, kind='cubic')(x)
dv = np.random.randint(2, 10, 21)
d = interp1d(np.arange(0, 101, 5), dv, kind='cubic')(x)
co = np.random.randint(20, 60, 21)
c = interp1d(np.arange(0, 101, 5), co, kind='cubic')(x)
windline(x, y, d, c)

,结果如下:

matplotlib line with different thickness and color

函数windline接受numpy数组作为参数,其中包含x,y,偏差(如每x值的厚度值)和颜色映射的颜色数组。我认为通过搞乱其他细节可以大大改善,但原则虽然不完美,但应该是可靠的。

答案 1 :(得分:2)

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
x = np.linspace(0,4*np.pi,10000) # x data
y = np.cos(x) # y data
r = np.piecewise(x, [x < 2*np.pi, x >= 2*np.pi], [lambda x: 1-x/(2*np.pi), 0]) # red
g = np.piecewise(x, [x < 2*np.pi, x >= 2*np.pi], [lambda x: x/(2*np.pi), lambda x: -x/(2*np.pi)+2]) # green
b = np.piecewise(x, [x < 2*np.pi, x >= 2*np.pi], [0, lambda x: x/(2*np.pi)-1]) # blue

a = np.ones(10000) # alpha
w = x # width

fig, ax = plt.subplots(2)

ax[0].plot(x, r, color='r')
ax[0].plot(x, g, color='g')
ax[0].plot(x, b, color='b')

# mysterious parts
points = np.array([x, y]).T.reshape(-1, 1, 2)
segments = np.concatenate([points[:-1], points[1:]], axis=1)
# mysterious parts

rgba = list(zip(r,g,b,a))

lc = LineCollection(segments, linewidths=w, colors=rgba)

ax[1].add_collection(lc)
ax[1].set_xlim(0,4*np.pi)
ax[1].set_ylim(-1.1,1.1)
fig.show()

enter image description here

我注意到这就是我的痛苦。