I am trying to make a plot like this one:
I want a 2D histogram with bar color proportional to the height and semi-transparent bars.
I tried to put together the examples provided here
x = randn(100, 2);
figure
hist3(x, [20 20]);
colormap(hot) % heat map
grid on
view(3);
%bar color
set(get(gca,'child'),'FaceColor','interp','CDataMode','auto');
%semitransparency
set(gcf,'renderer','opengl');
An example of the result is this:
The semi-transparency is absent.
I do not know if it is a problem of my Matlab version (R2014a) or if ---more probably--- I am messing up something. Maybe the axis handles?
Next
Outside this question: I would also like to add a transparent surface interpolating the histogram values (I got also some problems with this). I think I saw something like this on SO recently, but I cannot find it anymore. Does anyone have some hits?
You didn't actually change the surface transparency in your example. All you did was change renderers. Here's the extra line you would need:
set(get(gca,'child'),'FaceAlpha',0.8);
A value of 1 would be opaque, 0 invisible.
You may also want to change the edge line transparency too:
set(get(gca,'child'),'EdgeAlpha',0.2);
Related
I would like your help to plot the border of a scatter in Matlab and fill it with a specified colour.
Let me firstly show you how the scatter looks like.
scatter(x,y)
Now, let me show you what I have tried to design the border.
k = boundary(x,y);
plot(x(k),y(k));
which produces this
This is not what I want. Firstly, the scatter is nicely convex and I don't understand why boundary produces that weird shape. Secondly, I want to colour with blue inside the border.
Could you kindly advise on how to proceed? Also, when building the border I would prefer not to rely on the convexity of the scatter, because in some of my real examples the scatter is not convex.
Boundary
There is no easy way to get the boundary of a non-convex shape without any information on what is expected. When should the boundary follow the convex hull and when should deviate from it?
Matlab function boundary is generic, made to work with arbitrary input coordinates. It has a 'shrink factor' parameter s that can be tuned between 0 (convex hull) and 1 (highly non-convex), depending on the expected result.
% Make some x,y data with a missing corner
[x,y]=meshgrid(1:20);
sel=~(x>15 & y<=5);
x=x(sel);y=y(sel);
% Compute boundary with several values for s
k=boundary([x,y]); %Default shrink factor : 0.5
k_convhull=boundary([x,y],0);
k_closest=boundary([x,y],1);
% Plot the boundary:
plot(x,y,'ok') %black circles
hold on
plot(x(k),y(k),'-r') %red line
plot(x(k_convhull),y(k_convhull),'-g') %green line
plot(x(k_closest),y(k_closest),'-b') %blue line
The re-entrant corner is still somewhat cut, even with the 'shrink factor' set to 1. If this does not suit you, you will need to make your own function to compute the coordinates of the border.
Plot a surface
You need to use a patch object there.
p=patch(x(k3),y(k3),[1 .8 .8]);
uistack(p,'bottom')
[1 .8 .8] is the RGB color of the patch surface (light pink)
uistack is there to move the patch below the other graphic objects, because it is not transparent. It will still cover the axes grid, if any. Another option is :
p=patch(x(k3),y(k3),[1 0 0],'FaceAlpha',.2);
Here, the patch will be plain red and drawn on top of other objects, but has 80% transparency set through the alpha channel (0 is fully transparent, 1 is solid color).
Beware, the patch object class has so many options that is somewhat complex to handle beyond basic use cases like this one.
I have been trying to get semi-transparent circle-shape markers on a log-log scatter plot. MATLAB's own scatter plot function doesn't produce semi-transparent markers (see comments below), so I am using this wonderful tool scatter_patches from Central File Exchange and it works very well:
However, I am having issues adapting this code for a log-log scatter plot. In order to obtain a log-log scatter plot with this program, I need to fix two things:
1 . Change the axes to log scale. This can be achieved by adding following after line 61:
set(cax, 'XScale', 'log');
set(cax, 'YScale', 'log');
This produces correct log scale and grid points.
2 . However, after I fixed 1., the size of the markers was not uniform in my plot. On a log plot, the lower-value regions of the axes are zoomed-in. In the scatter_patches plot, the markers at the lower side of axes are bigger while they are smaller towards the higher-value side of axes. So, the marker size is not the same on the entire plot. I tried using log10(cSize) instead of cSize on lines 221-222, but this only slimmed the difference between the largest and smallest marker sizes. It didn't yield the same size markers on the plot.
If anyone has an idea of what I might be missing here, please share.
Any help would be greatly appreciated.
Since Matlab R2014b things got really easy. No additional functions from file exchange are required, just some undocumented features. The basic idea is to get the hidden handle of the markers and apply a value < 1 for the last value in the EdgeColorData to achieve the desired transparency.
Here we go:
%// example data
x = linspace(0,3*pi,200);
y = cos(x) + rand(1,200);
%// plot scatter, get handle
h = scatter(x,y);
drawnow; %// important
%// get marker handle
hMarkers = h.MarkerHandle;
%// get current edge and face color
edgeColor = hMarkers.EdgeColorData
faceColor = hMarkers.FaceColorData
%// set face color to the same as edge color
faceColor = edgeColor;
%// opacity
opa = 0.3;
%// set marker edge and face color
hMarkers.EdgeColorData = uint8( [edgeColor(1:3); 255*opa] );
hMarkers.FaceColorData = uint8( [faceColor(1:3); 255*opa] );
In the event it helps, I have written a collection of Matlab functions for creating semi-transparent markers in plots and legends. The files are available from MATLAB Central as the MarkerTransparency package. A few examples of how to use these functions are included in the download and there is also a Wiki on GitHub. A major benefit of this package is it enables the user to have the semi-transparent markers also appear in the legend. These functions have not been tested for scatter plots but might be easily adapted to meet your needs.
On line 192 change the line with this one:
hh(end+1) = patch( exp(cSize * sin(patchSpec) / ptsPerXUnit + xs(i)), exp(cSize * cos(patchSpec) / ptsPerYUnit + ys(i)), cColor, cPatchArgs{:}); and it will work.
I just add an exp()
Do the same operation on line 222 and 223 to be sure !
Work like a charm Anindya ;).
Is there some way of using the surf() style data format to create a heat map?
I have a bunch of scattered data of the form z=f(x,y) (so I used TriScatteredInterp to make it work with meshgrid) and I'd like to visualize z with a heat map. surf already does something similar to what I want, except you have to manually rotate the graph so the view is top down looking at the XY plane.
Basically, I'd like something similar to this:
But surf gives you this by default:
Although the answers here already show how to do this with surf, rendering the 3d surface feels a little like overkill...
pcolor creates the required images directly
(with slightly better results -surf has a gap next to the axes)
code
figure(1)
pcolor(peaks)
figure(2)
surf(peaks)
view(2)
results
pcolor
surf
Adding to Ben's answer, you can use the view command. view allows you to rotate your plot to whatever camera angle you wish.
In general, you call the command like so:
view(AZ, EL);
AZ is the azimuth or horizontal rotation, while EL is the vertical elevation. These are both in degrees.
In your case, once you plot your surf plot, use view(0, 90); before you go to the next subplot. view(0, 90); is the default 2-D view, and this looks directly overhead.
By doing this, you avoid having to rotate your plot manually, then using campos to determine what the camera position is at given your plot. view(0, 90); should give you what you need.
Sidenote
Doing view(2); also gives you the default 2D view, which is equal to view(0, 90); as we talked about. By doing view(3);, this gives you the default 3D view as seen in your plots. FWIW, the default azimuth and elevation for a 3D plot is AZ = -37.5, EL = 30, in degrees of course.
Rotate the view to what you want. Then type campos in the terminal. This shows you the camera position. You can then use campos( your_desired ) to set the camera position for future plots.
For example, the x, y view is usually:
campos([4.0000 2.5000 86.6025])
I want to paint some edges on my plot using gradient color according to their repetition percentage.
So the most repeated edge on my graph to be red, the next lesser to be orange and the edge with the less repetitions to be light beige.
The Percentage of the repetition can be obtained from a txt file.
The rest area of the plot i would like to stay intact in white color. Something like the next image (consider objects shape and size irrelevant, just the color gradient is what i am interested for).
How can i do this with matlab?
My approach so far:
EDIT it works with the addition of the hold all cmd
for jkl=1:size(edges,1)
plot(edges(jkl,1), edges(jk,2),'^','Color',[edgespercentage(jkl)/100 0 1], 'LineWidth', 2.5,'DisplayName', 'Edges with gradient color'); hold all
end
But as i see plot cant keep each iteration's color and plots at the end the last calculated color only (as expected).
Thank you in advance.
Solution found with the tip of David K (Thank you!)
I'm not sure if this is exactly what you want, but give it a shot:
mesh(xvals,yvals,zvals,repititionVals);
colormap('hot');
You can play around with colormap to get the exact shading you want, but I think either hot or autumn is the closest predefined map to what you're looking for
I have a 2D space in which a function value is defined (you can think of it as a manifold). Now I plotted the function value using contourf and changed the colormap to something softer than jet. So far it looks quite good.
Now I want to draw a line representing the state over time in my space. That is also possible using the the plot command. But I want some more improvements: There is an additional state that is hidden for now (value 0...50). I would like the line color to change according to this hidden state. So in a sense to apply a separate colormap to the line plotted by plot like for example in a waterfall plot.
Is this (or something similar) possible using matlab?
Thanks
If you want to either use interpolated shading or have the colours change with the colour map, then you want to plot your data as a mesh and set the edgecolor property appropriately. Note that in order to plot it as a mesh, then you will need to duplicate it so that it has a size of at least 2 in each direction.
h = mesh([X(:) X(:)], [Y(:) Y(:)], [Z(:) Z(:)], [C(:) C(:)], ...
'EdgeColor', 'interp', 'FaceColor', 'none');
You may also want to look at the MeshStyle property, if you want to plot multiple lines simultaneously.
This solution is also much nicer than the one used in cline because it only creates one graphics object, rather than n.
Have a look into the cline.m function from file exchange, I think it is exactly what you need.
I can recommend the Colored line entry from the file exchange. It has good feedback and uses the color map to define the displayed colours, I've use it sucessfully on a number of projects.