Stretch parts of axis (non uniform axis)

11 ビュー (過去 30 日間)
Cas Cas
Cas Cas 2018 年 1 月 19 日
コメント済み: Kelly Kearney 2018 年 1 月 20 日
Hi, I'm looking to create nonuniform axes in some plots. I'm aware of setting things like xticks and XScale, etc., but these change the spacing of the ticks themselves, rather than the data points. I'm looking to do something akin to a log or semi-log plot, where the data points themselves are stretched around accordingly, but not necessarily looking for logs.
For example, say I have x and y data and say the yticks = [0 500 1000 1500 2000 2500 3000] evenly spaced. The x data is very interesting for my purposes in the sub-1000 level so I'd like to stretch this so my plot: the data between 0 and 1000 now occupies the same amount of space that 0 to 2000 used to take and the data beyond 1000 is uniformly spaced as before, it's just now higher up in the figure. So with respect to the original figure, the new figure now takes up more vertical space and part of it is 'zoomed in', in a sense. I've attached an illustration.
Before
|
3000|
|
2500|
|
2000|
|
1500|
|
1000|
|
500|
|
0|--------------------------------------------------x
What I want:
|
3000|
|
2500|
|
2000|
|
1500|
|
1000|
|
|
|
500|
|
|
|
0|--------------------------------------------------x
and the x scale is the same in both.
I've played around with logs and manipulating ticks but the logs affect the entire dataset and while the ticks can be manipulated I've only been able to place the labels nonuniformly, without attention to the data itself.
Hope that makes sense.

回答 (1 件)

Kelly Kearney
Kelly Kearney 2018 年 1 月 19 日
You could scale the data appropriately and then overwrite the tick labels, but assuming you only have a few scaling blocks, I often accomplish this using two (or more) stacked axes, with the same data duplicated in each but with the y-scale set to adjacent values:
ax(1) = axes('position', [0.1 0.5 0.8 0.4]);
plot(1:100, rand(100,1)*3000);
ax(2) = copyobj(ax(1), gcf);
set(ax(2), 'position', [0.1 0.1 0.8 0.4]);
set(ax(1), 'box', 'off', 'xcolor', 'none');
set(ax(2), 'box', 'off');
set(ax(1), 'ylim', [1000 3000]);
set(ax(2), 'ylim', [0 1000]);
linkaxes(ax, 'x');
You may have to manually tweak tick labels to prevent overlap, but it's pretty straightforward otherwise.
  2 件のコメント
Cas Cas
Cas Cas 2018 年 1 月 20 日
編集済み: Cas Cas 2018 年 1 月 20 日
I thought about this but also wasn't sure where to begin. This works great with 2D plots, can it be implemented for 3D, such that the z-scale is now the axis that is manipulated?
To be clear, I can use the strategy to manipulate the z-axis but there is that gap in the middle of the curve (it should be a single curve plotted in 3D space). Fixing the overlapping of the axes is not an issue, just that gap in the middle. Any ideas? Thanks.
Kelly Kearney
Kelly Kearney 2018 年 1 月 20 日
Hmm, you can almost do it with some creative overlap of axes:
[x,y,z] = peaks;
h = plotgrid('size', [2 1], 'sp', -0.26);
for ii = 1:2
s(ii) = surf(h.ax(ii), x,y,z);
end
set(h.ax(1), 'zlim', [5 9], 'xcolor', 'none', 'ycolor', 'none');
set(h.ax(2), 'zlim', [-7 5]);
set(h.ax, 'color', 'none', 'xgrid', 'off', 'ygrid', 'off');
( plotgrid is one of my own functions, to create a custom grid of axes).
But there are still some odd clipping artifacts at the x-axis... not sure if there is a way around that. 3D axes are in general more difficult to hack; so much of their positioning is hidden under undocumented properties and inaccessible code.

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeAxis Labels についてさらに検索

製品

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by