如何在增加时将线条图下面的体积条形图填充为绿色,当它从之前的值减少时填充红色

时间:2016-04-15 09:22:27

标签: python matplotlib

enter image description here

import os
from matplotlib.backends.backend_pdf import PdfPages
import  pandas as pd
import matplotlib.pyplot as plt
import datetime as dt
plt.rcParams.update({'figure.max_open_warning': 0})

pp = PdfPages('multipage.pdf')

pth = "D:/Technical_Data/"
for fle in os.listdir(pth):
    df = pd.read_csv(os.path.join(pth, fle),usecols=(0,4,5,10))
    if not df.empty:
       df=df.astype(float)
       days = pd.to_datetime(df['indx'].astype(str), format='%Y%m%d')
       value = df['Close']
       open_v = df['MA_50']
       fig = plt.figure()
       plt.plot_date(x=days, y=value,fmt="r-")
       plt.plot_date(x=days, y=open_v,fmt="g-")
       fig.autofmt_xdate()
       plt.xticks(2013,2014,2015,2016)
       plt.ylabel("Price")
       plt.grid(True)
       pp.savefig()
       volume = df['Volume']
       plt.clf()
pp.close()

我使用此代码填充折线图,Y轴上有两列,X轴上有日期值。 我想再做一件事就是在折线图下方添加音量栏。当音量从先前值开始减小时颜色为红色,在增加时为绿色。

indx    open    High    Low Close   Volume
20141015    0.345   0.365   0.32    0.34    5540100
20141016    0.34    0.34    0.32    0.325   2044700
20141017    0.32    0.35    0.315   0.34    1818000
20141020    0.36    0.39    0.36    0.385   798900
20141021    0.39    0.41    0.39    0.395   2981500
20141022    0.415   0.43    0.39    0.39    2997900
20141023    0.4 0.4 0.37    0.375   458900
20141024    0.375   0.39    0.375   0.385   90000
20141027    0.38    0.38    0.355   0.38    562900
20141028    0.375   0.38    0.36    0.37    684300
20141029    0.375   0.38    0.365   0.37    339300

老实说,我自己尝试过这样做。与只有python相比,我发现matplotlib非常难。任何帮助表示赞赏

1 个答案:

答案 0 :(得分:1)

I've minimised you code down to just plot the bars; I'll leave it to you to incorporate into the rest of your script.

Here is how to plot the bars from your DataFrame, and then change the bars to red if they have a height less than the previous bar:

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

df = pd.DataFrame({
            'indx':[20141015,20141016,20141017,20141020,20141021,20141022,20141023,20141024,20141027,20141028,20141029],
            'Volume':[5540100,2044700,1818000,798900,2981500,2997900,458900,90000,562900,684300,339300]
            }).astype(float)


fig,ax = plt.subplots(1)

days = pd.to_datetime(df['indx'].astype(str), format='%Y%m%d')
volume = df['Volume']

# Plot all bars with green facecolor 
bars = ax.bar(np.array(days),volume,facecolor='g')

# Loop over bars
for i, bar in enumerate(bars):
    if i == 0: 
        continue

    # Find bar heights
    h = bar.get_height()
    h0 = bars[i-1].get_height()

    # Change bar color to red if height less than previous bar
    if h < h0: bar.set_facecolor('r')

fig.autofmt_xdate()

plt.show()

Basically you loop over the Rectangle patches created by ax.bar, and interrogate them to find their heights. Then, use .set_facecolor() to change the relevant bars.

Here's how it looks:

enter image description here

Final note: because the scales are so different between the price and the volume, you may want to use a twinx axes to plot the volume bars. See this example for more.