Matlab R2018a创建带双Y轴的OHLC-Volume股票图表求助
Matlab R2018a 双Y轴股票OHLC+成交量图表(修复数据光标显示问题)
问题核心
双Y轴配置下,Matlab默认数据光标只会读取左侧Y轴的数据源,导致点击成交量区域时显示的仍是股价数据,需要自定义数据光标回调函数来匹配对应坐标轴的数据源。
修复后的完整代码
% 模拟测试数据:日期+OHLC+成交量 dates = datetime(2024,1,1):datetime(2024,1,20); prices = rand(length(dates),4)*50 + 100; % 开盘、最高、最低、收盘 volume = randi([10000,50000],length(dates),1); % 创建画布与双Y轴 figure('Position',[100 100 1200 600]); yyaxis left; candle(dates, prices(:,1), prices(:,2), prices(:,3), prices(:,4)); % 画K线 ylabel('股价'); title('股票K线+成交量'); yyaxis right; bar(dates, volume, 'FaceColor',[0.2 0.6 0.8]); % 画成交量柱状图 ylabel('成交量'); xlabel('日期'); grid on; % 自定义数据光标回调函数,修复显示错误 dcm = datacursormode(gcf); set(dcm,'UpdateFcn',@customDataCursor); % 自定义回调函数实现 function txt = customDataCursor(obj,event_obj) % 获取当前点击的图形对象 target = event_obj.Target; % 获取点击的索引位置 pos = get(event_obj,'Position'); idx = find(target.XData == pos(1)); % 匹配日期对应的索引 % 判断是股价轴还是成交量轴 if strcmp(target.Parent.YAxisLocation,'left') % 读取OHLC数据 dateStr = datestr(target.XData(idx)); openP = target.YData(1,idx); highP = target.YData(2,idx); lowP = target.YData(3,idx); closeP = target.YData(4,idx); txt = {['日期: ', dateStr],... ['开盘: ', num2str(openP)],... ['最高: ', num2str(highP)],... ['最低: ', num2str(lowP)],... ['收盘: ', num2str(closeP)]}; else % 读取成交量数据 dateStr = datestr(target.XData(idx)); vol = target.YData(idx); txt = {['日期: ', dateStr],... ['成交量: ', num2str(vol)]}; end end
关键修改说明
- 双Y轴绑定:用
yyaxis left/right分别切换坐标轴,实现股价K线与成交量在同一画布的双刻度显示,替代subplot的分隔布局。 - 数据光标逻辑修复:通过
datacursormode设置自定义回调,判断点击目标的坐标轴位置(左/右),提取对应数据源的信息生成正确的显示文本。 - 适配对象数据结构:针对
candle对象的四维YData(对应OHLC)和bar对象的一维YData,分别处理数据提取逻辑,确保显示值与点击区域匹配。
轻量替代方案(无需自定义回调)
如果仅需快速预览数据,可给图形对象添加悬停提示,无需点击标注:
% 给K线添加悬停提示 candleObj = candle(dates, prices(:,1), prices(:,2), prices(:,3), prices(:,4)); for i=1:length(dates) tooltipStr = sprintf('日期: %s\n开盘: %.2f\n最高: %.2f\n最低: %.2f\n收盘: %.2f',... datestr(dates(i)),prices(i,1),prices(i,2),prices(i,3),prices(i,4)); set(candleObj(i),'TooltipString',tooltipStr); end % 给成交量柱添加悬停提示 barObj = bar(dates, volume); for i=1:length(dates) tooltipStr = sprintf('日期: %s\n成交量: %d',datestr(dates(i)),volume(i)); set(barObj.Children(i),'TooltipString',tooltipStr); end
内容的提问来源于stack exchange,提问作者user2635886
相关产品推荐
相关产品推荐

