I am currently having trouble while adding transparency to my pie charts.
I can't set using FaceAlpha or EdgeAlpha and using alpha alone kind of rips the edges of the chart when compiling the eps file.
Any tips?
figure;
subplot(1,2,1)
h=pie3(P1,[0 0 0 1 1])
set(h,'EdgeColor','none','LineStyle','none')
hold on
colormap cool
hold on
subplot(1,2,2)
h=pie3([PF PG],[1 0 ],{'X1','X2'})
set(h,'EdgeColor','none')
colormap cool
%alpha(0.5)
print teste -depsc2
The output of pie3 is an array of handles. Some are handles to surfaces, some are to patches, and others are for text. You need to select the sub-set of these handles that actually have EdgeAlpha and FaceAlpha properties. You can do this using findobj.
h = pie3(rand(1,5), [0 0 0 1 1]);
set(findobj(h, '-property', 'FaceAlpha'), 'FaceAlpha', 0.2);
set(findobj(h, '-property', 'EdgeAlpha'), 'EdgeAlpha', 0);
When exporting to an EPS though, transparency is not supported. Also, since you have transparency in your figure, MATLAB will use the OpenGL renderer which causes EPS files to not be rendered as you expect. You could try to use export_fig to get a better result.
It is really difficult to figure out what you are asking.
My code sample shows a way for tighter control over objects inside a figure.
I hope you can modify my example to something you can work with.
(If it isn't, please insert images, and more detailed information about your problem, and also add values of P1, PF, PG).
Matlab orders figure objects is a kind of "tree" structure.
The structure is:
figure -> axes-> object
object
...
object
-> axes-> object
object
...
object
The axes is a children of a figure, and objects are children of axes.
The following code gets array of axes handles:
%Get handles to two axes inside figure;
h_axes_arr = get(gcf, 'Children');
The following code gets array of objects handles (children of first axes):
%Array of handles - children of first axes.
h_arr = get(h_axes_arr(1), 'Children');
h = h_arr(1);
get(h, 'Type') Query the type of the first object.
Here is my code sample:
P1 = [1,3,0.5,2.5,2];
PF = 1;
PG = 2;
figure;
subplot(1,2,1)
h=pie3(P1,[0 0 0 1 1]);
set(h,'EdgeColor','none','LineStyle','none')
hold on
colormap cool
hold on
subplot(1,2,2)
h=pie3([PF PG],[1 0 ],{'X1','X2'});
set(h,'EdgeColor','none')
colormap cool
%alpha(0.5)
%Get handles to two axes inside figure;
h_axes_arr = get(gcf, 'Children');
%Array of handles - children of first axes.
h_arr = get(h_axes_arr(1), 'Children');
for i = 1:length(h_arr)
%Handle to specific children.
h = h_arr(i);
if (isequal(get(h, 'Type'), 'surface'))
%Set trasparency only if handle type is 'surface'
set(h, 'FaceAlpha', 0.5); %Set Alpha to 0.5
end
end
%Array of handles - children of second axes.
h_arr = get(h_axes_arr(2), 'Children');
for i = 1:length(h_arr)
%Handle to specific children.
h = h_arr(i);
if (isequal(get(h, 'Type'), 'surface'))
%Set trasparency only if handle type is 'surface'
set(h, 'FaceAlpha', 0.3); %Set Alpha to 0.5
end
end
%print teste -depsc2
Result:
I know it's ugly...
I hope you can make something useful out of it.
Related
I want to add something to make my phase portrait more understandable. Nevertheless, I can't find anything (I found this
https://se.mathworks.com/help/matlab/ref/colorspec.html
https://se.mathworks.com/matlabcentral/fileexchange/11611-linear-2d-plot-with-rainbow-color
https://se.mathworks.com/help/symbolic/mupad_ref/linecolortype.html
) but it is not what I need.
I would really like to see the color of the line of the phase portrait changing depending of if it is at the beginning or at the end of the simulation.
I found this idea which seems great :
I don't understand at all what he has done (the code is I suppose written here:
https://blogs.mathworks.com/pick/2008/08/15/colors-for-your-multi-line-plots/ )
but It would be great if I can plot a one line function which color varies depending of the time. If moreover, like on the picture, I can have have a scale on the right: it would be awesome.
So for now, I have that :
data = readtable('test.txt');
figure('Name','Phase' , 'units','normalized','outerposition',[(8/100) (0.3- 16/100) 0.5 0.7]);
hold on
plot(data{:,2},data{:,3}, 'k.', 'LineWidth',1.5 );
plot(data{:,4},data{:,5}, 'r.', 'LineWidth',1.5 );
xL = xlim;
yL = ylim;
line([0 0], yL); %x-axis
line(xL, [0 0]); %y-axis
title(['Phase portrait'])
xlabel('f')
ylabel('f '' ')
hold off
I read the values of the function in a .txt file, and then I plot the 2nd/3rd columns and 4/5th columns. The first column is the time evoluting.
Do you have any idea :)?
Thank you!
There are several ways to go about this to be honest.
However it makes a bit easier if you let us know what your time data is.
Do you plot your time data on the x (or y) axis or is it a different additional data set. Should it be an additional data set then you can consider it like z-data, plotted on the Z-axis or/and as a color.
Below is an example of what you can do by making a 3D plot but displaying it in 2D, this allows you to add the colorbar without too many problems.
x=0:5;
y=0:5;
z=rand(1,6); %random data to simulate your time
xx=[x' x']; %this allows you to plot the data using surf in 3d
yy=[y' y']; %same as for xx
z1=zeros(size(xx)); % we don't need z-data so we're making it a matrix of zeros
zc=[z' z']; %input here your time data values, if x/y then you can just use those instead of z
hs=surf(xx,yy,z1,zc,'EdgeColor','interp') %// color binded to "z" values, choose interp for interpolated/gradual color changes, flat makes it sudden
colormap('hsv') %choose your colormap or make it yourself
view(2) %// view(0,90)
hcb=colorbar; %add a colorbar
I found this, thanks to another user on stackoverflaw.
data = readtable('4ressorspendule.txt');
n = numel(data.Var1);
c = size(data,2);
figure('Name','Phase' , 'units','normalized','outerposition',[(8/100) (0.3 - 16/100) 0.5 0.7]);
for i=1:n
hold on
plot(data{i,2},data{i,3},'.','Color',[1 (1-i/n) 0] ,'MarkerSize',4);
plot(data{i,4},data{i,5},'.','Color',[0 (i/n) (1-i/n)],'MarkerSize',4);
end
xL = xlim;
yL = ylim;
line([0 0], yL); %x-axis
line(xL, [0 0]); %y-axis
title(['Phase portrait'])
xlabel('f')
ylabel('f '' ')
hold off
For faster operation I want to update a plot with different data in MATLAB. If I use plot3 it will open a new figure every time, which is time consuming. I cannot use hold command as I do not want earlier plots. Any suggestion?
Create the plot object initially and then update its 'XData','YData' and 'ZData' properties according to the new values:
axis([0 1 0 1]);
h = plot3(NaN,NaN,NaN,'.'); %// intiallize plot object
for n = 1:20
x = rand(1,100);
y = rand(1,100);
z = rand(1,100); %// example new data for the plot
set(h, 'XData', x, 'YData', y, 'ZData', z); %// update properties of plot object
pause(.1)
end
This is the short version of one of my previous answers to a different question.
If you want to create a new plot to the previous figure window by using Plot Objects/functions like e.g. plot3, the hold command is necessary in any case (apart from you're using Core Graphics Objects).
For deleting the previous plots you have two options:
clf (clear figure) which will reset the figure and axes objects (delete all axes objects inside the figure) and therefore is probably not much of a performance plus.
cla (clear axes) which will just clear the axes (delete all graphics objects inside the axes object) but keep all labels and axes limits.
I think the last option is what you're looking for.
Test code:
figure
plot( [10 20], [10 20] );
xlim( [0,100] ); ylim( [0,100] ); hold on
xlabel( 'x' );
ylabel( 'y' );
pause(1)
cla
plot( [20 30], [20 30] );
I want to show only the legend for a group of data in MATLAB.
The reason I want to do this is that I want to export the legend to .eps, but I only want the legend, not the plots.
Is there a way to turn off the plots and remove them from the figure, but still show just the legend centered?
This seems to do the trick:
plot(0,0,'k',0,0,'.r') %make dummy plot with the right linestyle
axis([10,11,10,11]) %move dummy points out of view
legend('black line','red dot')
axis off %hide axis
There is probably a lot of whitespace around the legend. You could try to resize the legend by hand, or save the plot and use some other program to set the bounding box of the eps.
The chosen solution by Marcin doesn't work anymore for R2016b because MATLAB's legend will automatically gray out invisible plots like this:
Neither turning off the automatic update of the legend nor changing the TextColor property afterwards fixes this. To see that, try Marcin's modified example:
clear all; close all;
figHandle = figure;
p1 = plot([1:10], [1:10], '+-');
hold on;
p2 = plot([1:10], [1:10]+2, 'o--');
legHandle = legend('text1', 'text2');
%turn off auto update
set(figHandle,'defaultLegendAutoUpdate','off');
set(p1, 'visible', 'off');
set(p2, 'visible', 'off');
set(gca, 'visible', 'off');
%set legend text color to black
legHandle.TextColor = [0 0 0];
The result remains the same. (To avoid throwing my laptop through the window) and fix this without zooming, which might leave fragments of the plot in the way, I wrote a function that fixes the legend and saves it to a file (with frame):
function saveLegendToImage(figHandle, legHandle, ...
fileName, fileType)
%make all contents in figure invisible
allLineHandles = findall(figHandle, 'type', 'line');
for i = 1:length(allLineHandles)
allLineHandles(i).XData = NaN; %ignore warnings
end
%make axes invisible
axis off
%move legend to lower left corner of figure window
legHandle.Units = 'pixels';
boxLineWidth = legHandle.LineWidth;
%save isn't accurate and would swallow part of the box without factors
legHandle.Position = [6 * boxLineWidth, 6 * boxLineWidth, ...
legHandle.Position(3), legHandle.Position(4)];
legLocPixels = legHandle.Position;
%make figure window fit legend
figHandle.Units = 'pixels';
figHandle.InnerPosition = [1, 1, legLocPixels(3) + 12 * boxLineWidth, ...
legLocPixels(4) + 12 * boxLineWidth];
%save legend
saveas(figHandle, [fileName, '.', fileType], fileType);
end
Tips for use:
fileType is a string that specifies a valid argument for saveas(), such as 'tif'.
Use it after you have plotted everything you want to appear in your legend, but without extra stuff. I'm not sure if all potential elements of a plot contain an XData member that isn't empty.
Add other types of displayed things that you want deleted, but are not of type line if there are any.
The resulting image will contain the legend, its box, and a little bit of space around it the legend is smaller than the minimum width (see Minimum Width of Figures in MATLAB under Windows). However, this is usually not the case.
Here is a complete example using the function from above:
clear all; close all;
fig = figure;
p1 = plot([1:10], [1:10], '+-');
hold on;
p2 = plot([1:10], [1:10]+2, 'o--');
legendHandle = legend('myPrettyGraph', 'evenMoreGraphs');
saveLegendToImage(fig, legendHandle, 'testImage', 'tif');
I think that you need to "hide" the elements you don't want in your plot, leaving out only the legend. For example,
clear all; close all;
figure;
p1 = plot([1:10], [1:10], '+-');
hold on;
p2 = plot([1:10], [1:10]+2, 'o--');
legend('text1', 'text2');
set(p1, 'visible', 'off');
set(p2, 'visible', 'off');
set(gca, 'visible', 'off');
I have some points in a 'jet' colormap. The points have a coefficient that can go from 0 to 1, but usually they dont cover all the range, e.g 0.75-0.9.
When I plot those points I colour them so 0.75 is the lesser colour in the colormap and 0.9 is the maximum color in the colormap, so all the colormap is shown. What I want to do is show that in the colorbar also. When I plot the colorbar the labels on it go to 64, but I want them from 0.75 to 0.9. How can I do that?
EDIT
I don't think the code itself helps a lot but here it goes, just in case. In the colors variable I convert the ZNCC to the range of the colormap.
EDIT2
I found the reason why caxis is not working for me. Here is the code:
%this is why it doesnt work
im=imread('someimageyouwanttotest_inRGB.png')
imshow(im)
points=[1, 2;1 , 2 ;0.3,0.7]
ZNCC=points(3,:)
cmap=colormap('jet');
colors=cmap(round( ((1-min(ZNCC))+ZNCC-1).*(size(cmap,1)-1)/max((1-min(ZNCC))+ZNCC-1))+1,: );
hold on
for i=1:length(ZNCC)
plot(points(1,i),points(2,i),'.','Color',colors(i,:));
end
colorbar()
hold off
I think that is your code displays all your colours correctly then rather just set up the colour bar first on no image:
points=[1, 2;1 , 2 ;0.3,0.7]
ZNCC=points(3,:)
cmap=colormap('jet');
caxis([min(ZNCC) max(ZNCC)]);
colorbar();
hold on
%this is why it doesnt work
im=imread('someimageyouwanttotest_inRGB.png')
imshow(im)
colors=cmap(round( ((1-min(ZNCC))+ZNCC-1).*(size(cmap,1)-1)/max((1-min(ZNCC))+ZNCC-1))+1,: );
for i=1:length(ZNCC)
plot(points(1,i),points(2,i),'.','Color',colors(i,:));
end
hold off
I can't test it as I don't have imshow :/
If caxis is not working for you, you could store the return from colorbar - it is a handle to the colorbar object. Then you can set its properties, like 'YTick' and 'YLim'. The full list of properties you can set is the same as the Axes Properties (because the colorbar is just an axes object, after all).
Here is an example:
% Generate some random data
z = rand(10);
[x, y] = meshgrid(1:size(z, 1));
% Plot colour map
pcolor(x, y, z);
shading interp; % Comment out to disable colour interpolation
colormap jet;
% Setup colorbar
c = colorbar();
set(c, 'YTick', [0.75 0.875 1]); % In this example, just use three ticks for illustation
ylim(c, [0.75 1]);
It is only necessary to do this once, after you've finished plotting.
Edit: If you need the limits and ticks automatically from the data, then you can do something like
% Find the limits
lims = [min(z(:)) max(z(:))];
% Function for rounding to specified decimal places
dprnd = #(x, dps)round(x*(10.^dps))./(10.^dps);
% Generate ticks
nTicks = 5;
nDps = 2;
ticks = dprnd(linspace(lims(1), lims(2), nTicks), nDps);
set(c, 'YTick', ticks);
I was trying use the code shown below to plot in such a way that each iso-surface will be different in color and there will be a color bar at the right. I made a ss(k) color matrix for different colors. Number of iso-surfaces is 10 but I have only 8 colors. That's why I wrote ss(9)='r' and ss(10)='r'.
I need a solution to plot the iso-surface with different color and bar at the right side.
ss=['y','m','c','r','g','b','w','k','r','r']
k=1;
for i=.1:.1:1
p=patch(isosurface(x,y,z,v,i));
isonormals(x,y,z,v,p)
hold on;
set(p,'FaceColor',ss(k),'EdgeColor','none');
daspect([1,1,1])
view(3); axis tight
camlight
lighting gouraud
k=k+1;
end
Another possibility is to draw the patches with direct color-mapping (by setting the property 'CDataMapping'='direct'), while assigning the 'CData' of each patch to an index in the colormap of your choice. This is in fact recommended for maximum graphics performance.
Consider the following example:
%# volumetric data, and iso-levels we want to visualize
[x,y,z,v] = flow(25);
isovalues = linspace(-2.5,1.5,6);
num = numel(isovalues);
%# plot isosurfaces at each level, using direct color mapping
figure('Renderer','opengl')
p = zeros(num,1);
for i=1:num
p(i) = patch( isosurface(x,y,z,v,isovalues(i)) );
isonormals(x,y,z,v,p(i))
set(p(i), 'CData',i);
end
set(p, 'CDataMapping','direct', 'FaceColor','flat', 'EdgeColor','none')
%# define the colormap
clr = hsv(num);
colormap(clr)
%# legend of the isolevels
%#legend(p, num2str(isovalues(:)), ...
%# 'Location','North', 'Orientation','horizontal')
%# fix the colorbar to show iso-levels and their corresponding color
caxis([0 num])
colorbar('YTick',(1:num)-0.5, 'YTickLabel',num2str(isovalues(:)))
%# tweak the plot and view
box on; grid on; axis tight; daspect([1 1 1])
view(3); camproj perspective
camlight; lighting gouraud; alpha(0.75);
rotate3d on
I also included (commented) code to display the legend, but I found it to be redundant, and a colorbar looks nicer.
Matlab usually plots different iso-surfaces in different colors automatically, so you don't need to care about that. What kind of bar do you need? A colorbar or a legend? Either way, it is just to use the colorbar or legend function..
%Create some nice data
[x y z] = meshgrid(1:5,1:5,1:5);
v = ones(5,5,5);
for i=1:5
v(:,:,i)=i;
end
v(1:5,3:5,2)=1
v(1:5,4:5,3)=2
%Plot data
for i=1:5
isosurface(x,y,z,v,i)
end
%Add legend and/or colorbar
legend('one','Two','Three','Four')
colorbar
Since the color bar encodes value->color, it is impossible to do what you ask for, unless there is no intersection in z-values between all pairs of surfaces. So the solution below assumes this is the case. If this is not the case, you can still achieve it by adding a constant value to each surface, so to separate the surfaces along the z axis, and eliminate any intersection.
The solution is based on constructing a colormap matrix of piecewise constant values, distributed similarly to the z values of your surfaces. So for example, if you have 3 surfaces, the first has z values between 1 and 10, the 2nd between 11 and 30, and the 3rd between 31 and 60, you should do something like this (I plot in 2D for simplicity)
r = [1 0 0];
g = [0 1 0];
b = [0 0 1];
cmap = [r(ones(10,1),:); g(ones(20,1),:); b(ones(30,1),:)];
z1 = 1:10;
z2 = 11:30;
z3 = 31:60;
figure; hold on
plot(z1,'color',r)
plot(z2,'color',g)
plot(z3,'color',b)
colorbar
colormap(cmap)
More complex colormaps (i.e, more colors) can be constructed with different mixtures of red, green, and blue (http://www.mathworks.com/help/techdoc/ref/colorspec.html)