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非常难。任何帮助表示赞赏
答案 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:
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.