简体   繁体   English

matlab中的二级y轴3D图(冲浪,网格,冲浪)

[英]Secondary y-axis in matlab 3D plot (surf, mesh, surfc)

I am trying to add a secondary y-axis with different units to a 3D plot. 我正在尝试将具有不同单位的辅助y轴添加到3D绘图中。 在此输入图像描述

[m2_array, ~ , ~] = F_readBin('amb.bin');
amb = m2_array(:,:,lat);

surfc(light,'LineWidth',0.001); 
ylim([1 24]); xlim([1 size(light,2)]); title(['@ ',num2str(lat),'°N']);
xticks([0:50:size(m2_array,2)]);
labels=cellstr(num2str((day_start:50:day_end)')); xticklabels(labels);
xlabel('Season days'); ylabel('Daytime{[hours]}');zlabel('surface light 
[\mumol m^2 s^-^1]')
colormap winter;

However,all solutions I can find eg yyaxis seem to work only for 2D plots. 但是,我能找到的所有解决方案,例如yyaxis似乎只适用于2D图。 Is there a work around for surf, mesh, surfc plots? 是否有冲浪,网状,冲浪地块的工作?

Not sure if this is what you are looking for, but I guess a basic approach to adding secondary axes to a 3D plot would be the same as for 2D (as far as I know a 2D plot in matlab is just a 3D-plot viewed from above). 不确定这是否是您正在寻找的,但我想将辅助轴添加到3D绘图的基本方法与2D相同(据我所知,matlab中的2D绘图只是查看的3D绘图从上面)。

The idea is that you place a second set of axes on top of the first, then tweak it to fit your requirements, eg by hiding unused axes and making the secondary background transparent. 我们的想法是在第一组轴上放置第二组轴,然后调整它以满足您的要求,例如隐藏未使用的轴并使辅助背景透明。 This is explained in the Matlab documentation here . 这是Matlab的文件中说明这里

For 3D this is a bit tricky because of the default axis and label locations, but that's where undocumentedmatlab comes to the rescue. 对于3D而言,由于默认的轴和标签位置,这有点棘手,但这就是未记录的matlab来拯救的地方。 Using the FirstCrossOverValue and SecondCrossoverValue properties of the Axes ' NumericRuler objects ( XAxis , YAxis , ZAxis ), we can position the secondary axis in the desired location. 使用FirstCrossOverValueSecondCrossoverValue所述的性质Axes ' NumericRuler对象( XAxisYAxisZAxis ),我们可以在所需的位置定位在辅助轴。

The basic idea is illustrated in the example below. 基本思想如下例所示。 This is for the z-axis, but the same approach can be used for y or x. 这是针对z轴的,但是相同的方法可以用于y或x。

clear; close all; clc

% Dummy data from matlab example
[X,Y,Z] = peaks(25);

% Primary axes with some arbitrary viewpoint and labels
hs = surf(X,Y,Z); % Get surface object
ha = hs.Parent; % Get parent Axes
ha.View = [25, 40]; % Set arbitrary view point
xlabel 'xa';
ylabel 'ya';
zlabel 'za';
grid on

% Secondary axes on top of primary, using same view point
hb = axes('view',ha.View);
hb.ZLim = [0 7]; % Arbitrary axis limits
zlabel 'zb'; 

% Hide secondary background and x and y rulers
hb.Color = 'none'; % Transparent background
hb.XAxis.Visible = 'off';
hb.YAxis.Visible = 'off';

% Move z-ruler to opposite corner (from undocumentedmatlab)
hb.ZAxis.FirstCrossoverValue = 1; % x-location of z-ruler [normalized]
hb.ZAxis.SecondCrossoverValue = 1; % y-location of z-ruler [normalized]

Note that this basic example breaks down when you start rotating the axes manually, or zooming in or out. 请注意,当您开始手动旋转轴或放大或缩小轴时,此基本示例会中断。 You would need to add some methods that link the two axes together in order to take care of that. 您需要添加一些将两个轴链接在一起的方法,以便处理这些问题。

The result would be: 结果将是: 三维图中的辅轴示例

As illustrated in the answer from Dennis , you could make use of some undocumented features to add an extra axis. Dennis的答案所示,您可以使用一些未记录的功能来添加额外的轴。 This has a few drawbacks, the obvious being that undocumented features have a tendency to change without notice. 这有一些缺点,显而易见的是,未记录的功能在没有通知的情况下有变化的趋势。 Additionally, adding an extra x or y axis in the same fashion (ie on the opposite side) would cause it to be occluded by the plot and not be very useful. 另外,以相同的方式(即在相对侧)添加额外的xy轴将导致它被绘图遮挡并且不是非常有用。 Achieving an effect where the axes are stacked up on one side, as the answers to this question illustrate, would be more desirable in 3D. 正如这个问题的答案所示,实现轴在一侧堆叠的效果在3D中更为理想。 However, this could be somewhat cluttered, and I have yet to find a robust way to do this that plays well with changes in the plot (ie rotation, zooming, changing limits, etc). 然而,这可能有些杂乱,我还没有找到一种强有力的方法来完成这一点,可以很好地适应绘图的变化(即旋转,缩放,更改限制等)。

Instead of adding another axis line, a more compact solution that doesn't depend on undocumented features would be to piggyback on an existing axis' tick marks and simply add an additional set of tick labels at a new scale. 而不是添加另一个轴线,不依赖于未记录的特征的更紧凑的解决方案将是捎带在现有轴的刻度线上,并且只需以新的比例添加一组额外的刻度标签 The additional set of tick (and axis) labels can be colored using TeX markup to differentiate them. 可以使用TeX标记对附加的刻度线(和轴)标签进行着色以区分它们。

I wrapped some code into a prototype function that does this. 我将一些代码包装到一个原型函数中。 The inputs are the axes handle, a string ( 'X' , 'Y' , or 'Z' ) for the axes to modify, a new set of axis limits for the new scale (which will be mapped to the current limits), the color of the new labels (as an RGB triple ), and a string for the new axis label : 输入是轴手柄,要修改的轴的字符串( 'X''Y''Z' ),新标度的一组新的轴限制(将映射到当前限制),新标签的颜色(作为RGB三元组 )和新轴标签的字符串:

function add_scale(hAxes, axisStr, newLimits, newColor, newLabel)

  % Get axis ruler to modify:
  axisStr = upper(axisStr);
  hRuler = get(hAxes, [axisStr 'Axis']);

  % Create TeX color modification strings:
  labelColor = ['\color[rgb]{' sprintf('%f ', hRuler.Label.Color) '}'];
  tickColor = ['\color[rgb]{' sprintf('%f ', hRuler.Color) '}'];
  newColor = ['\color[rgb]{' sprintf('%f ', newColor) '}'];

  % Compute tick values for new axis scale:
  tickValues = hRuler.TickValues;
  limits = hRuler.Limits;
  newValues = newLimits(1)+...
              diff(newLimits).*(tickValues-limits(1))./diff(limits);

  % Create new tick labels:
  formatString = ['\' tickColor hRuler.TickLabelFormat '\\newline\' ...
                  newColor hRuler.TickLabelFormat '\n'];
  newTicks = strsplit(sprintf(formatString, [tickValues; newValues]), '\n');

  % Update tick and axis labels:
  hRuler.Label.String = {[labelColor hRuler.Label.String]; ...
                         [newColor newLabel]};
  hRuler.TickLabels = newTicks(1:(end-1));

end

And here's an example: 这是一个例子:

[X, Y, Z] = peaks(25);
hSurf = surfc(Z);
hAxes = gca;
ylabel('Distance (inches)');
add_scale(hAxes, 'Y', hAxes.YLim.*2.54, [1 0 0], 'Distance (cm)');

在此输入图像描述

The new tick labels (in red) are added below the existing tick labels, as is the new axis label. 新的刻度标签(红色)将添加到现有刻度标签下方,新轴标签也是如此。 It may be possible to create listeners to update the new labels automatically (such as when tick marks are changed), but I haven't worked out all the details of this yet. 有可能创建监听器以自动更新新标签(例如更改刻度标记时),但我还没有弄清楚这一点的所有细节。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM