Python matplotlib图表背景取决于数据

Python matplotlib图表背景取决于数据,python,matplotlib,background,Python,Matplotlib,Background,我试图绘制一些数据,并希望根据数据有一个彩色背景 在下面的示例中,我希望data1和data2位于左yaxis,data3位于右yaxis。这是有效的。但另外,我还试图根据数据3对背景进行着色 我需要如何格式化数据才能使其正常工作 import matplotlib.pyplot as plt from datetime import datetime as dt import matplotlib.dates as md fig, ax1 = plt.subplots(constrained

我试图绘制一些数据,并希望根据数据有一个彩色背景

在下面的示例中,我希望data1和data2位于左yaxis,data3位于右yaxis。这是有效的。但另外,我还试图根据数据3对背景进行着色

我需要如何格式化数据才能使其正常工作

import matplotlib.pyplot as plt
from datetime import datetime as dt
import matplotlib.dates as md

fig, ax1 = plt.subplots(constrained_layout=True)

data1 = [51.2, 51.2, 51.2, 50.7, 50.7, 50.5, 50.4, 50.7, 50.6]
data2 = [46.5, 46.1, 46.2, 46.3, 46.4, 46.3, 46.2, 46.1, 45.5]
data3 = [ 0.0,  1.0,  1.0,  1.0,  0.0,  0.0,  0.0,  0.0,  0.0]

timestamps = [1524614516, 1524615134, 1524615587, 1524615910, 1524616235, 1524616559, 1524616866, 1524617189, 1524617511]
timestamps_ = [dt.utcfromtimestamp(x) for x in timestamps]

for data in (data1,data2):
    ax1.plot(timestamps_, data, marker='.', linestyle='-')
ax1.set_ylabel("degC")

ax2 = ax1.twinx()
ax2.plot(timestamps_, data3, marker='x', linestyle='-')
ax2.pcolor(ax2.get_xlim(), ax2.get_ylim(), zip(timestamps_, data3), cmap='RdGn', alpha=0.3) 
ax2.set_ylabel("ON OFF")       

ax1.set_title("Mytitle")
for tick in ax1.xaxis.get_major_ticks():
    tick.label1.set_horizontalalignment('right')
    tick.label1.set_rotation(35)
xfmt = md.DateFormatter('%Y-%m-%d %H:%M:%S')
ax1.xaxis.set_major_formatter(xfmt)

plt.show()
错误消息:

Traceback (most recent call last):
  File "/home/tobias/workspace/python_pyplot_test/main.py", line 25, in <module>
    ax2.pcolor(ax2.get_xlim(), ax2.get_ylim(), zip(timestamps_, data3), cmap='RdGn', alpha=0.3) 
  File "/usr/local/lib/python2.7/dist-packages/matplotlib/__init__.py", line 1855, in inner
    return func(ax, *args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/matplotlib/axes/_axes.py", line 5732, in pcolor
    X, Y, C = self._pcolorargs('pcolor', *args, allmatch=False)
  File "/usr/local/lib/python2.7/dist-packages/matplotlib/axes/_axes.py", line 5576, in _pcolorargs
C.shape, Nx, Ny, funcname))
TypeError: Dimensions of C (9, 2) are incompatible with X (2) and/or Y (2); see help(pcolor)
回溯(最近一次呼叫最后一次):
文件“/home/tobias/workspace/python\u pyplot\u test/main.py”,第25行,在
ax2.pcolor(ax2.get_xlim(),ax2.get_ylim(),zip(时间戳,数据3),cmap='RdGn',alpha=0.3)
文件“/usr/local/lib/python2.7/dist packages/matplotlib/_init__;u.py”,第1855行,内部
返回函数(ax,*args,**kwargs)
文件“/usr/local/lib/python2.7/dist packages/matplotlib/axes/_axes.py”,第5732行,pcolor格式
十、 Y,C=self.\u pcolorargs('pcolor',*args,allmatch=False)
文件“/usr/local/lib/python2.7/dist-packages/matplotlib/axes/_-axes.py”,第5576行,在_-pcolorargs中
C.shape,Nx,Ny,funcname)
类型错误:C(9,2)的尺寸与X(2)和/或Y(2)不兼容;请参阅帮助(pcolor)

以下是您想要的最低解决方案:

import matplotlib.pyplot as plt
from datetime import datetime as dt
import matplotlib.dates as md
import numpy as np


data3 = np.array([ 0.0,  1.0,  1.0,  1.0,  0.0,  0.0,  0.0,  0.0,  0.0])

x=np.arange(9)
xp,yp=np.meshgrid(x,data3)
xp=xp.astype(float)-0.5
bgcolor=np.ones(xp.shape)*data3[None,:]

plt.pcolor(xp,yp,bgcolor) 
plt.plot(x, data3, marker='x', linestyle='-')
我取出了第二个轴和所有勾号,因为它们与问题本身无关。

另一个选项是使用:

使用
axvspan
pcolor
之间的一个区别是
axvspan
绘制的垂直跨度(矩形)在
y
方向上没有边界,而
pcolor
矩形没有边界。因此,如果使用
zoom
按钮调整绘图大小,则
axvspan
矩形将拉伸到无穷大(粗略地说),而缩小
pcolor
矩形将显示白色区域。这没什么大不了的,只是觉得你想知道


还请注意,如果垂直跨距从第一个数据点开始并延伸到下一个数据点,则永远不会使用
data3
中的最后一个值。(九个数据点构成八个垂直跨距)。但是,如果将垂直跨距放在数据点的中心,那么每个数据点都位于跨距的中心,则可以使用
data3
中的所有9个值

取消注释下面注释的代码(注释掉
左时间戳
右时间戳
)的当前定义以查看差异



谢谢你的建议,但我还是不知道如何把它和时间戳结合起来。我将采用Unutbuth的另一个解决方案,问题是pcolor将2d数组作为输入,而您的输入是1d。注意行
xp=xp.astype(float)-0.5
我必须将背景色和数据居中。您可以将其添加到unutbu的解决方案中谢谢unutbu的帮助!结果正是我想做的。我将使用注释代码,因为它看起来更漂亮!谢谢!
import numpy as np
import matplotlib.pyplot as plt
from datetime import datetime as dt
import matplotlib.dates as md

def topydates(timestamps):
    return [dt.utcfromtimestamp(x) for x in timestamps]
fig, ax1 = plt.subplots(constrained_layout=True)

data1 = [51.2, 51.2, 51.2, 50.7, 50.7, 50.5, 50.4, 50.7, 50.6]
data2 = [46.5, 46.1, 46.2, 46.3, 46.4, 46.3, 46.2, 46.1, 45.5]
data3 = [ 0.0,  1.0,  1.0,  1.0,  0.0,  0.0,  0.0,  0.0,  1.0]

timestamps = np.array([1524614516, 1524615134, 1524615587, 1524615910,
                       1524616235, 1524616559, 1524616866, 1524617189, 1524617511])
timestamps_ = topydates(timestamps)

for data in (data1,data2):
    ax1.plot(timestamps_, data, marker='.', linestyle='-')
ax1.set_ylabel("degC")

ax2 = ax1.twinx()
ax2.plot(timestamps_, data3, marker='x', linestyle='-')

# if you want the axvspans to be centered around the data points
# widths = np.diff(timestamps)
# midpoints = timestamps[:-1] + widths/2.0
# timestamps_left = topydates(np.r_[timestamps[0]-widths[0]/2, midpoints])
# timestamps_right = topydates(np.r_[midpoints, timestamps[-1] + widths[-1]/2.0])
# if you uncomment the code above, then comment-out the line below:
timestamps_left, timestamps_right = timestamps_[:-1], timestamps_[1:]

cmap = plt.get_cmap('RdYlGn')
for left, right, val in zip(timestamps_left, timestamps_right, data3):
    print(left, right)
    color = cmap(val)
    ax2.axvspan(left, right, facecolor=color, alpha=0.3)

ax2.set_ylabel("ON OFF")       

ax1.set_title("Mytitle")
for tick in ax1.xaxis.get_major_ticks():
    tick.label1.set_horizontalalignment('right')
    tick.label1.set_rotation(35)
xfmt = md.DateFormatter('%Y-%m-%d %H:%M:%S')
ax1.xaxis.set_major_formatter(xfmt)

plt.show()