Second y axis for the same dataset
10 visualizzazioni (ultimi 30 giorni)
Mostra commenti meno recenti
I have a dataset that I want to view in two different scales. The relationship between the two scales is logarithmic. A simple example would be to view the temperature variation in a room in both fahrenheit and celcius during day 1. Let's say i have the data for day 2 and i want to view the difference. I found in the file exchange a function called plot2axes that was amazing in plotting the data in two scales separately, but now I can't use it for the difference, due to the logarithmic/exponential nature of the relationship between my two scales. plotyy doesn't work because it plots two separate plots, which i don't want. the best solution would be a piece of code that lets me customise the relationship between two axis, while the simplest would be a way to hide one of the plotyy plots without messing up neither the other one nor one of the axis (which is what happens if you try to use "'visible','off'").
6 Commenti
dpb
il 22 Dic 2015
Modificato: dpb
il 22 Dic 2015
[ax, p1,p2] = plotyy(x,y,x,10.^((Convert(y)/20)/1000),'semilogx','loglog');
Undefined function 'Convert' for input arguments of type 'double'.
Hence I can't really tell for sure what your case was, but if the constant is roughly same order of magnitude as the values, then the resulting transformed data is also essentially a random blob of values over some other range.
Hence, if you put the same data on two overlaid axes, since the data are essentially the same shape in both coordinate systems, it's pretty much inevitable that the two are going to overlap.() Expecting one to somehow have a different appearance than the other in this case is just a set of unrealizable expectations. It would undoubtedly be better in this case to use *subplot instead; I don't see any way to create a single axes in which such data wouldn't be confounded.
(*) Actually, you could force them to not be overlaid by adjusting an offset and scaling of the axes as mentioned earlier to cause them to not each take up the full range of the axes and one to reside in the upper region and t'other in lower parts. But, that's essentially building a subplot by other means. You can, of course, change the default spacing of the axes and all to make the two axes there be closer and eliminate the blank space to make it look more like one. Something along those lines could be more pleasing given your desires, perhaps.
But, I come back to the fact that if the data are at all like that generated by the sample it's just a fact of life that the two lines are going to look very similar and therefore if they are given a sizable fraction of the display space on a single axis they'll inevitably clash.
dpb
il 23 Dic 2015
OK, mayhaps I've been thinking of this wrongly...I was thinking from your example of two separate datasets because I got (I guess) off on the wrong foot with the example given of the temperature and temperature difference.
Instead, are you looking for a general, not necessarily linear, scaling of a secondary axis that corresponds to an arbitrary transformation of a single waveform or function? In that case, Star got much closer although by default the secondary axis generated that way will have a skewing problem because it's a linear transformation instead of nonlinear as I noted in that comment following his Answer.
If, that is the issue, then as the author of the FEX submission noted, plot2axes breaks down as well as its scale function is also limited to a linear transformation.
So, in summary, you would in fact expect one line and two axes rather than my obsessing on trying to make two lines not confound each other???
Risposte (3)
Star Strider
il 22 Dic 2015
To plot the second y-axis without showing the associated line plot, set the colour to 'none':
r1 = (-85+20).*rand(1000,1) + -20;
r2 = (-85+20).*rand(1000,1) + -20;
x = 1:size(r1);
y = r1-r2;
[ax, p1,p2] = plotyy(x,y,x,10.^(y/20/1000),'semilogx','loglog');
set(p2, 'Color','none')
I left out the ‘Convert’ call because I don’t have it.
1 Commento
dpb
il 22 Dic 2015
That works if the data are precisely colinear on the two scales but it's not the right scaling in general, Star. But, it's a solution I hadn't thought of previously that may have value in certain cases.
If the RH axis limits are set to correspond to the min/max limits on the LH axis, then the two extremes will be right but how close the intermediate points are depends on what convert really does. If it's nonlinear as OP describes, there will be skewing of some sort.
dpb
il 22 Dic 2015
Modificato: dpb
il 22 Dic 2015
Alternative to display overlapping data succinctly...
for i=1:2, hAx(i)=subplot(1,2,i); end % create base left/right axes objects
pos=get(hAx(1),'position'); % get default position vector LH
pos(3)=0.5-pos(1); % adjust width to hit middle
set(hAx(1),'position',pos) % and set new position/size
pos(1)=0.5; % RH left position, use adjusted width above
set(hAx(2),'position',pos)
semilogx(hAx(1),x,y1);
loglog(hAx(2),x,y2)
set(hAx(2),'yAxisLoc','right')
This isn't perfect in just a few minutes(*) but gives an idea you might explore as being more able to represent these kinds of waveforms.
The first refinement I'd explore would be a small delta, dW less than the 0.5 midpoint so that there's just enough break between the two to make it clear there are two separate waveforms. Shouldn't take but a smidge...
*ADDENDUM
Realized ain't all that difficult--
dW=0.005; % delta away from midpoint for width
pos=get(hAx(1),'position'); % get default position vector LH
pos(3)=0.5-dW-pos(1);
set(hAx(1),'position',pos) % and set new position/size
pos(1)=0.5+dW;
set(hAx(2),'position',pos,'yAxisLoc','right')
set(hAx,'box','on','nextplot','add') % box and "hold on"
See how that looks for spacing. NB: the hold on for the axes; otherwise when you subsequently plot or semilog or loglog, things get reset (like most noticeably the 'yAxisLoc' property) and you've got to do 'em again. It's done here via set as hold won't accept an array of handles.
0 Commenti
dpb
il 24 Dic 2015
Modificato: dpb
il 24 Dic 2015
OK as follow-up to my above comment -- try the following with some of your real data and let us know how it succeeds...w/o a real case to test I've no idea what you're expecting but seems to work with at least an attempt from what you've given (which is still incomplete as we really don't know what convert did...
yLim1=get(ax(1),'ylim'); % get default limits from the LH axis
yLim1to2=10.^(convert(yLim1)/20/1000); % transform those limits
set(ax(2),'ylim',yLim1to2) % set RH axis limits to match
If it's nonlinear-enough, there will still be some fuzziness. If it is actually only a power of 10 as in the above, then the log transform does linearize so it works identically. Other nonlinear functions won't behave so well, of course.
2 Commenti
dpb
il 24 Dic 2015
OBTW, Star, if this is the case OP was searching for, your solution in addition is also good; it would leave simply the one line shown.
dpb
il 26 Dic 2015
One last comment -- if the nonlinearity isn't logarithmic then there's no way with a conventional axes object to make the two functions coincide identically the full range of the two axes; the only option one has with axes scaling is linear or logarithmic. If convert is neither, then only way would be to forego actually plotting the RH side and using line and text to draw and label intermediate ticks where they belong after the above scaling of the axes to the two limits. In essence this would be the same exercise as above for the two limits but retrieving the LH tick vector for the input y.
Vedere anche
Categorie
Scopri di più su Axis Labels in Help Center e File Exchange
Prodotti
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!