我正在尝试使用
candlestick
的一些数据创建一个 XAUUSD
图表,它代表外汇市场中的黄金。
X轴(时间轴)由于假期有间隙,而且实时市场数据也有间隙,因为它是
1-minute timeframe
,并且在某些时间间隔内可能没有任何交易,特别是在00:00但是也可能在其他时间。
我想从情节中删除这些空白。当我必须使用
matplotlib.pyplot
时,我该如何做到这一点?
这是我的代码:
def plot_data(df, candle_length):
green_df = df[df.Close > df.Open].copy()
green_df["Height"] = green_df["Close"] - green_df["Open"]
red_df = df[df.Close < df.Open].copy()
red_df["Height"] = red_df["Open"] - red_df["Close"]
doji_df = df[df.Close == df.Open].copy()
fig = plt.figure(figsize=(16,8))
ax = fig.add_subplot()
ax.grid(linestyle='--')
if len(green_df) > 0:
ax.vlines(x=green_df.index, ymin=green_df["Low"], ymax=green_df["High"], color="#00CC00")
ax.bar(x=green_df.index, height=green_df["Height"], width=candle_length/1440, bottom=green_df["Open"], color="#00CC00")
if len(red_df) > 0:
ax.vlines(x=red_df.index, ymin=red_df["Low"], ymax=red_df["High"], color="#CC0000")
ax.bar(x=red_df.index, height=red_df["Height"], width=candle_length/1440, bottom=red_df["Close"], color="#CC0000")
if len(doji_df) > 0:
ax.vlines(x=doji_df.index, ymin=doji_df["Low"], ymax=doji_df["High"], color="#888888")
ax.hlines(xmin=pd.to_datetime(doji_df.Timestamp - candle_length*30, unit="s"), xmax=pd.to_datetime(doji_df.Timestamp + candle_length*30, unit="s"), y=doji_df["Open"], colors="#888888")
fig.tight_layout()
plot_data(get_candles(symbol, timeframe, candle_count, candle_length, max_time_period), candle_length)
输出: 图片
我发现this上面写着:
dt_all = pd.date_range(start=df['Date'].iloc[0],end=df['Date'].iloc[-1], freq = '5min')
dt_obs = [d.strftime("%Y-%m-%d %H:%M:%S") for d in df['Date']]
dt_breaks = [d for d in dt_all.strftime("%Y-%m-%d %H:%M:%S").tolist() if not d in dt_obs]
fig.update_xaxes(rangebreaks=[dict(dvalue = 5*60*1000, values=dt_breaks)])
它与
plotly
配合得很好,但不能解决我的问题,因为 update_xaxes
中的数字没有
pyplot
功能
是否有与上述 Plotly 代码等效的 Pyplot 或任何其他方法来实现该目的?
这是一种在多个连续轴上绘图的方法,遵循 matplotlib 文档的 broken axis 示例,以及plotly 中的
breaks_idxs
的想法。
import numpy as np
import matplotlib.pyplot as plt
# Data
x = np.array([1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 15, 16, 17, 18, 19])
y = np.random.randn(len(x))
std = np.random.rand(len(x))
# Getting that the way you want
breaks_idxs = [5, 10]
# Splitting the data for multiple axes
xs = np.split(x, breaks_idxs)
ys = np.split(y, breaks_idxs)
stds = np.split(std, breaks_idxs)
n_splits = len(breaks_idxs) + 1
# Creating the axes without horizontal spaces between them
fig, axes = plt.subplots(ncols=n_splits, gridspec_kw={"wspace": 0}, figsize=(10, 5))
# Can't sharey=True, or can't turn of spines individually
ymin = (y - std).min()
ymax = (y + std).max()
for i, (ax, x_, y_, std_) in enumerate(zip(axes, xs, ys, stds)):
# Plot info
ax.set_title(f"Week {i + 1}")
ax.vlines(x_, y_ - std_, y_ + std_, color="C0", lw=2)
ax.scatter(x_, y_, c="C1", marker="s")
# Make sure axes share y range
ax.set_ylim(ymin * 1.1, ymax * 1.1)
# Make sure x-axis transitions are smooth
# might introduce a computation for "0.5"
ax.set_xlim(x_[0] - 0.5, x_[-1] + 0.5)
# Remove spines and ticks
sbs = ax.get_subplotspec()
if not sbs.is_first_col():
ax.spines.left.set_visible(False)
ax.yaxis.set_ticks([])
if not sbs.is_last_col():
ax.spines.right.set_visible(False)
plt.show()