Matlab: create lines with equal physical length along each axis - matlab

I want to make scale bars with ticks, and I want the ticks on the X and Y bars to have the same physical length, regardless of the relative lengths, dimensions, or "modes" of the axes (at least at the time the ticks are created). I was hoping that daspect() would give me the information I need for this, but daspect() seems to be mostly useless for interrogating aspect ratio. For instance, if I generate a plot that Matlab gives an XLim of [0 3.5] and a YLim of [0 1], then daspect() gives [3.5 1 ...] regardless of how I have the figure sized on the screen. That's obviously not accurate or helpful. Is there another function, or maybe a way to make daspect() give useful information without manipulating the plot?

daspect() returns garbage on a typical plot. It's because of the stretch-to-fill feature, which distorts the plot to fill up the figure space, rendering the values in DataAspectRatio inaccurate. Instructions for turning off stretch-to-fill can be found here.
I also found a workaround if you want to leave stretch-to-fit on, which is to temporarily set PlotBoxAspectRatioMode to 'manual,' which has the effect of changing the value of DataAspectRatio to match what is on screen.
figure;plot(0.1:0.1:pi,sin(0.1:0.1:pi))
pbaspect manual
val = daspect
pbaspect auto
Or a safer way to do it if you want a generally useful script (e.g. in case PlotBoxAspectRatioMode is already manual and you don't want to change that) would be:
pbaspectMode = get(gca,'PlotBoxAspectRatioMode');
pbaspect manual;
val = daspect;
set(gca,'PlotBoxAspectRatioMode',pbaspectMode);
I'm not sure whether this will have any intermittent or pernicious side effects, however.
According to The Mathworks support:
The technique of setting bpaspect to manual and then back may be "safe" (although I wouldn't be surprised if there are side effects), but a better way is to divide:
real_daspect = daspect./pbaspect;

Related

How to reverse the direction of Y-Axis of MatLab figure generated by `imagesc()` function

I am trying to display data in a matrix using imagesc() function but it is showing row index in decreasing order (Assuming origin at left-bottom). Any idea what mistake i could be making or how to correct this?
The matrix only has zeros and ones in it.
Set Ydir property of the current axes to normal
By default, imagesc uses reverse for YDir
set(gca,'YDir','normal');
See Documentation for Axes properties
Before:
After:
Note: This completely flips the inside data as well (it supposed to). As you are dealing with matrices, I hope this is what you want.
If you don't want to affect inside data, you need to change order of YTickLabels instead.
There's another option which requires slightly less code:
axis ij
Reverse the coordinate system so that the y values increase from top to bottom.
As in this case (as it is already reversed), you could use
axis xy
To get back to normal, so that y values increases from bottom to top.
As mentioned in the docs of axis.

Why is errorbar whisker length dependent on X

I am running a simulation in Matlab 2015 which creates data each round, so I am plotting a number of single errorbar series individually. Here's a sample code and the output plot:
figure
xlim([0 30])
hold on
errorbar(1,2.0,1.9,16.5,'x')
errorbar(15,2.0,1.9,16.5,'x')
errorbar(25,2.0,1.9,16.5,'x')
errorbar(10,2.0,1.9,16.5,'x')
errorbar(30,2.0,1.9,16.5,'x')
errorbar(5,2.0,1.9,16.5,'x')
errorbar(20,2.0,1.9,16.5,'x')
The weirdness is that the whisker length appears to be dependent on my X value. As you can see it increases from left to right, even though I did not plot them from left to right. The single-sided width of each whisker is 0.01*x.
Why is this happening, and how can I fix it? This doesn't seem like intended functionality. Ideally I would just manually set the width of each whisker, but I can't find a way to do that. There was a function posted on the MFX a while back, but that was made for R2007b and no longer works. The errorbar series properties do not give any indication that the whiskers can even be affected at all. Any help here would be greatly appreciated!

Is there any way to "stretch" a given colormap for a larger range?

I'm building a MATLAB program to visualize a simulation of particles clustering.
Our simulation usually runs with around 10000 particles and the clusters might get to be around 5000 particles in size and I wanted to color the clusters by size so i inserted the following code:
a=[1 1 1 500]; %means x=1 y=1 z=1 and clustersize=500
colormap(flipud(pink));
scatter3(a(:,1),a(:,2),a(:,3),repmat(10,numel(a(:,1)),1),a(:,4),'filled','MarkerEdgeColor', 'k')
and after a cluster reaches a certain size it becomes "saturated" and sticks with the same color even when growing to be twice that size.
I've tried using colormap(hsv(1024)); to make a larger color map but that isn't very good for me either since i want to use a uniform gradient from light to dark and now necessarily mess around with lots of various colors, as the aren't distinguishable enough.
Any ideas how to stretch colormap(flipud(pink)); so it'll get saturated only around 5000? or alternatively let me know if there is some other solution that'll give me a higher "dynamic range"
Ok, so while trying to answer Luis Mendo I started making a gif of the simulation, and decided to add a colorbar; to the figure, then I saw that the colorbar stretched itself from figure to figure.
I found the code
lowrange = 1;
highrange = 5000;
caxis manual
caxis([lowrange highrange]);
which I used earlier for another simulation worked to predetermine the colorbar;'s range. this apparently meant the range of the colormap was also "stretched" or used the predetermined range.
Here are two clips from the simulation, one with the caxis fix, and one without, notice how the colorbar changes without the fix, that caused the particles to loop black(saturated) the for most of the simulation, regardless of the cluster size.
simulation without the corrected caxis code
simulation with corrected caxis code

How to neatly cut off an extreme value in a plot that compresses the rest of a plot?

So basically, the graph labeled "Thermal Wind" has an extreme value that compresses the y-values for all the other plots, making it much harder to see any of the individual variations in the other plots. Is there a way to neatly cut off this extreme value? I could just rescale the y limit to a maximum of 40, but then this looks ugly.
As for the alternative I've tried - it's here:
I would recommend trying to plot it on a log scale. The function you'll want to consider using is semilogx, though for completeness I recommend also reading the help file on loglog.
Alternately, you could use subplot to generate multiple plots, one of which is zoomed into a region of interest.
Are the outlier points errors in the data, or do they represent extreme cases?
If they are not valid data, just manually exclude them from the data, plot the graph, and include a text clarification when describing the graph. If they are valid data, then trimming them would misrepresent the data, which isn't a good thing.
Graphs of data aren't art: their main goal isn't to be pretty; it's to provide a useful visualization of data. There are some minimum requirements on appearance, however: the axes have to be labeled, the units have to be meaningful, the different curves have to be visually distinct, etc. As long as your graph has these things, you shouldn't expect to lose marks for presentation.
There are two approaches that I use:
One approach would be transform the data so it will fill the plot nicely. Make the transform so that it wouldn't touch the range - say -10 to +10. In your case you could choose it so that 100 transforms to +15 and -100 to -15.
For clarity you need to then also set and label the y ticks appropriately. And for nice style make sure the line changes slope when it goes over the border.
I plot the data as is. But set the axis limits say from -10 to +10. Where points lay outside I place upwards and downwards triangles along the border to mark in which direction the "outliers" would be. Obviously this is only good when there aren't too many.

how to always display "labels" on axis X

If I zoom several time graph all labels from axis X disapear (go away) and there are no visible axis X labels so it is not possible to understand the part of graph where am I.
How can I force matlab to always display labels on axis X and to update them automatically while zooming and to display enough digits so "neighboor" labels must be different.
it depends, are you manually setting the tick marks yourself ('XTick' and 'XTickLabel' axis properties)?
Try this simple example
plot(sin(1:10), 'o-')
without changing anything, you can zoom as much as you want, and the tick labels will always be visible
EDIT
The root cause of the problem is the same as the one raised in your other question, datetick function will manually set the tick labels, thus disabling automatic update on zoom/pan.
The good news is there are already submissions on FEX that tries to solve this exact problem with DATETICK
I run into the same problem even on the new version of MATLAB (r2014). MATLAB does not display sufficient x-axis tick labels as you zoom-in. After several experiments I found the following workaround. Following is a plot before implementing the solution. MATLAB displays only three XTick labels on the x-axis even though there is sufficient space for more (there are often even less labels as you zoom in more).
Suspecting that MATLAB thinks that it does not have sufficient space to display more labels, a workaround can be to rotate the labels. To do that, after you issue the plot commands, e.g.
plot(tsX);
hold on;
plot(tsY);
plot(tsZ);
add the following command
set(gca,'XTickLabelRotation',90);
Now MATLAB plots with more labels
I am going to report this as a bug to the MATLAB guys.