Last week I explained how to customize plot-lines with transparency and color gradient. Today I wish to show how we can achieve similar effects with plot markers. Note that this discussion (like the preceding several posts) deal exclusively with HG2, Matlab’s new graphics system starting with R2014b (well yes, we can also turn HG2 on in earlier releases).
As Paul has noted in a comment last week, we cannot simply set a 4th (alpha transparency) element to the MarkerFaceColor and MarkerEdgeColor properties:
>> x=1:10; y=10*x; hLine=plot(x,y,'o-'); drawnow; >> hLine.MarkerFaceColor = [0.5,0.5,0.5]; % This is ok >> hLine.MarkerFaceColor = [0.5,0.5,0.5,0.3]; % Not ok While setting the 'MarkerFaceColor' property of Line: Color value must be a 3 element numeric vector
Lost cause? – not in a long shot. We simply need to be a bit more persuasive, using the hidden MarkerHandle property:
>> hMarkers = hLine.MarkerHandle; % a matlab.graphics.primitive.world.Marker object >> hMarkers.get EdgeColorBinding: 'object' EdgeColorData: [4x1 uint8] EdgeColorType: 'truecolor' FaceColorBinding: 'object' FaceColorData: [4x1 uint8] FaceColorType: 'truecolor' HandleVisibility: 'off' HitTest: 'off' Layer: 'middle' LineWidth: 0.5 Parent: [1x1 Line] PickableParts: 'visible' Size: 6 Style: 'circle' VertexData: [3x10 single] VertexIndices: [] Visible: 'on' >> hMarkers.EdgeColorData' % 4-element uint8 array ans = 0 114 189 255 >> hMarkers.FaceColorData' % 4-element uint8 array ans = 128 128 128 255 |
As we can see, we can separately attach transparency values to the marker’s edges and/or faces. For example:
hMarkers.FaceColorData = uint8(255*[1;0;0;0.3]); % Alpha=0.3 => 70% transparent red |
And as we have seen last week, we can also apply color gradient across the markers, by modifying the EdgeColorBinding/FaceColorBinding from ‘object’ to ‘interpolated’ (there are also ‘discrete’ and ‘none’), along with changing the corresponding FaceColorData/EdgeColorData from being a 4×1 array to a 4xN array:
>> colorData = uint8([210:5:255; 0:28:252; [0:10:50,40:-10:10]; 200:-10:110]) colorData = 210 215 220 225 230 235 240 245 250 255 0 28 56 84 112 140 168 196 224 252 0 10 20 30 40 50 40 30 20 10 200 190 180 170 160 150 140 130 120 110 >> set(hMarkers,'FaceColorBinding','interpolated', 'FaceColorData',colorData) |
This can be useful for plotting comet trails, radar/sonar tracks, travel trajectories, etc. We can also use it to overlay meta-data information, such as buy/sell indications on a financial time-series plot. In fact, it opens up Matlab plots to a whole new spectrum of customizations that were more difficult (although not impossible) to achieve earlier.
Throughout today, we’ve kept the default FaceColorType/EdgeColorType value of ‘truecolor’ (which is really the same as ‘truecoloralpha’ as far as I can tell, since both accept an alpha transparency value as the 4th color element). If you’re into experimentation, you might also try ‘colormapped’ and ‘texturemapped’.
p.s. – other chart types have similar internal objects that can be customized. For example, bar charts have internal Face and Edge properties that correspond to internal objects that can be similarly modified:
>> get(h.Edge) AlignVertexCenters: 'on' AmbientStrength: 0.3 ColorBinding: 'object' ColorData: [4×1 uint8] ColorType: 'truecolor' DiffuseStrength: 0.6 HandleVisibility: 'on' HitTest: 'off' Layer: 'middle' LineJoin: 'miter' LineStyle: 'solid' LineWidth: 0.5 NormalBinding: 'none' NormalData: [] Parent: [1×1 Bar] ... |
Thanks, this is useful — setting an alpha component is a better way to visualise density than applying jitter.
Is it possible to make the area plots transparent? Or do I have to use the patch command?
@Grunde – Yes this is possible, but I don’t think you need to use any undocumented features for this. Assuming you used the builtin area function to generate the plot, you can set the FaceAlpha property of the area-plot’s children.
Alternatively, you can use the builtin alpha function.
The area object doesn’t have any children. And the area object itself doesn’t have a FaceAlpha property. At least in 2014b.
Dear Yair,
For some reason on Matlab 2014b the area alpha doesn’t seem to work. I copy/paste your sample and run it. Although it doesn’t throw any error, it seems to ignore the settings in h(2).Face.ColorData(4). I can change it to whatever value, but the transparency of the faces (areas) don’t change at all.
Am I missing something?
It works for me… Perhaps you are using software emulation (not hardware acceleration) in your opengl. Type opengl(‘info’) to find out.
Dear Yair,
Thanks for you reply. I did some further tests and I think I found at least one problem. When I run the area command within a loop for plotting multiple sets of data into one plot it sometimes happens that the x-axis is resized to fit the data. Whenever this command is called the previous settings are discarded and all areas have the same color and no transparency. Can you confirm that using e.g.
breaks the settings for transparency?
Hi Again,
So, finally I figured it out how to circumvent the problem with the resizing. I simply had to apply the color and alpha settings at the very end of my plotting script (after settings xlims, adding legends, etc.). Then this works just fine.
Thanks again for your kind help and for putting this down for others to read!
Cheers
As far as I can tell, changing the EdgeColorBinding (or FaceColorBinding) from ‘object’ to ‘interpolated’ or ‘discrete’ is problematic. Entering Edit Plot mode (the pointer icon on the toolbar) resets the ColorBinding and ColorData back to ‘object’ and the original color.
Short Example:
This will generate a simple line with the first point red. Clicking the Edit Plot icon will reset all markers.
Even without changing EdgeColorBinding/FaceColorBinding from ‘object’ to ‘interpolated’ or ‘discrete’, the original color is reset back to the original color if a legend is added to the plot:
Does anyone have a solution for this?
Unfortunately, the same happens even when hitting ‘Edit’ -> ‘Copy Figure’ or trying to export it. I built a bunch of pretty figures with this but they are stuck within Matlab 🙁
You can try to place your customization code in a short function that you’d reference in the axes CreateFcn property and/or its MarkedClean event (using addlistener).
Yup, that works. Thanks so much, Yair. It’s a pretty awful hack job to achieve what I feel should be basic functionality but here we go:
and the keep function:
Note that when adding a legend the symbol comes up wrong. But at least I can export my scatter plots now…
Thanks for all the useful tips. I have a nitpicky question: when I change any hidden property of my figures I have to manually select the line of code and execute it by itself (sometimes I have to repeat this twice before it works). It will not just execute itself if I run it as a script or a function. Any idea why that is?
@Claire – it should work in a script/function as well. You are probably doing something wrong. Perhaps the figure is not visible when it reaches that line of code, or maybe you just need to add a pause(0.1) and/or drawnow before your property-modification line.
@Yair, I just saw your response. Thanks so much, adding the drawnow did the trick!
Hi.
Thanks for writing this post. I find transparent markers really essential for making dense scatter plots readable. However, when I run your code (see below), hMarkers is empty. I use 2014b on Win8. Any idea what’s going wrong?
@Fabian – simply add a drawnow call after your plot(), before accessing
hLine.MarkerHandle
.splendid. Thank you 🙂
Hello!
I’m trying this in matlab r2015a, I got the same problem as Fabian, but the drawnow command does not solve the problem.
Hey Yair,
thank you very much for these very valuable tips! They really open up a plethora of charting options that come in very handy, in my case.
Do you have any further details / documentation about ‘MarkerHandle’? For example, I am wondering about how to use the xxBinding properties; how exactly do ‘object’, ‘interpolated’, ‘discrete’ and ‘none’ work?
One more question: in MATLAB, I frequently need to generate a 2D scatter plot with:
(1) use individual marker transparencies to encode a 3rd variable (e.g. age of people). Your post solves this 🙂
(2) use individual marker sizes to encode a 4th variable (e.g. number of people). I’m stuck here: I do not know of any possibility to vary the marker sizes individually. While there are appropriate object properties (Size for the Line class, and MarkerSize for the MarkerHandle class), these are apparently required to be scalars.
I’d love to set these to a vector. For performance reasons, I would like to avoid calling ‘line’ several times in a loop.
Do you have any idea or suggestion?
Thank you very much!
Philip
an example of what I’m talking about can be found here:
http://glowingpython.blogspot.co.at/2011/11/how-to-make-bubble-charts-with.html
@Philip – If you use scatter or scatter3, then you can set the SizeData property to be either a scalar or a vector the same size as the data.
Absolutely terrific! I was not aware of SizeData…
Thank you very much!! Hope this will help others as well.
Thanks for this useful tip! I’m still finding my way around MATLAB, and unfortunately I’m stuck – was wondering if I can access the hidden MarkerHandle in Matlab 2013a? Not able to find any documentation on this. Thanks for any help.
Cheers
@Priyanka – this functionality is only available in Matlab’s new graphics system (HG2), which became officially available in Matlab release R2014b (i.e., 3 releases after yours). If you wish to access its undocumented and still unstable functionality in your R2013a, then follow the instructions here: http://undocumentedmatlab.com/blog/hg2-update#testing
The keepAlpha of Fabian does a good job preventing Matlab to get rid of the transparency again when, e.g., legend is called. Is there a way to convince ‘legend’ to show the transparent markers properly too?
Hi Dani and Yair,
I have been using the keepAlpha trick with success as well to keep transparency on the figure Markers when toggling the legend. I am, as Dani, very keen to find a solution to keep the transparency in the legend markers as well.
Any hint into where to look for a begining of solution would be very welcome. For example, is there a hidden way to access the handles to the Markers that are in the legend ? Would the optimal solution be to create a function myLegend that would design the legend from scratch ?
BR
@Dani & @Christopher:
The legend function clears marker customizations such as transparency. You can restore the transparency by re-updating hMarkers.FaceColorData following the legend call.
In order to customize the legend itself, we need to dig into the legend object’s hierarchy. This is not too difficult:
simple.
Hi Yair,
Thank you for the terrific post! I have a question on printing figure to pdf (or any format really!) and retaining the transparency. It used to be that zbuffer would do the trick (loses vector format) but at least the transparency property is not lost. In >2014, zbuffer is no longer an option. I was wondering if you have had any success in using other renderers? Thanks again.
EZ
@EZ – transparency output is (and always was) problematic in Matlab. In general, painters does not render transparencies so in HG2 (R2014b onward) we need to use the slower opengl renderer for export. Try using
print -dpdf
and/or the export_fig utility. You’ll probably still run into limitations with either of these though.(sorry about directly emailing – I missed your warnings)
Hi – re your column on assigning transparency to plot markers: I tried the code on a simple example and all was well. Then I tried a tight loop, plotting a single point at a time (doing this to assign a different color to each point in the graph), and invariably within a few loop cycles, when I grab the “plothandle.MarkerHandle”, it’s empty. In these cases, the class of this empty object is “Matlab.graphics.GraphicsPlaceholder”
while when the operation is successful, the class is:
“matlab.graphics.primitive.world.Marker”
I’ve tried things like clearing variables every loop, putting in a delay timer, and so on, with no luck. Any idea what’s going on?
many thanks
Carl
Cross-referenced solution (as for Fabian’s issue above, to add a call to drawnow): http://stackoverflow.com/a/35070679/233829
Yep, at least for me drawnow solved the problem. I was the OP for that SO question, btw 🙂
Yes of course. But since you neglected to come back here and update that you have found a solution, causing me and other readers extra effort to look for a solution, I thought it would at least be nice of me to inform other readers here that a solution was found. Next time please be more considerate of others.
Great article, it was very helpful.
I found an issue, though I don’t think it’s related to this method “per se”. When I try to export the figure, the transparency of the markers is lost, but the transparency of other objects is kept (for example, patches).
Is there a solution for this? or any way to export the figure exactly as it’s shown in the Figure window?
I’m using 2014b and I’ve tried exporting to png and pdf using both the painter and the OpenGL renderers with similar results.
The above does not work on Matlab 2016a. I get no transparency at all.
>> ver
—————————————————————————————————-
MATLAB Version: 9.0.0.341360 (R2016a)
MATLAB License Number: STUDENT
Operating System: Microsoft Windows 7 Home Premium Version 6.1 (Build 7601: Service Pack 1)
Java Version: Java 1.7.0_60-b19 with Oracle Corporation Java HotSpot(TM) 64-Bit Server VM mixed mode
The dots are still the same color. No transparency. Nothing changed.
@Nasser – this is because you did not read carefully, and so you missed 3 important commands!
Hi! I’m would like to get a better view of many points in a scatter3 plot, but unfortunately the transparency is lost once I rotate the plot. Is there a way to fix that?
@Lukas – Matlab automatically removes transparency when you modify the axes (e.g., by rotation). You could attach a callback listener to the axes’
MarkedClean
event that will restore the transparency once Matlab finishes doing its internal updates.Hello,
Is it possible to do with point cloud plot command: pcshow();? I want to change size of Brushing marker.
I get this:
I’ve been looking into hidden lines, axes properties, but I can’t find it anywhere.
@Pawel – you have a bug in your code. As the error message indicates,
hLine
in your code is a handle to the axes, not to the line.Sweet. But when I try to print, Matlab2014b clears everything. I created events listeners for markers in both plot and legends. That works fine to rebuild after a click in ‘show plot tools’; but won’t work in print preview… 😐
@Marconi – this has already been reported by others on this blog. Matlab’s print and saveas functions clear such transparencies, and there is no known workaround for this. You can use a screen capture utility to capture the actual appearance and then print from that screen-capture.
Use MATLAB2015b! It will print transparencies correctly.
I found that when I upgraded to Matlab 2016a, the transparency functions will generate figures in the correct way but will not print the transparencies. Importantly, 2015b prints figures properly!
Thank you so much for this page, it is fantastic! I finally have my transparent scatter plots back in 2015a!
PS I found a workaround to save transparency changes in matlab 2015a: if you use saveas to save the file as *.svg, then open in Inkscape (free) and export as a png there, transparency values are saved.
I also found I needed to build in a brief pause in my script before obtaining the marker handle to avoid getting the following error: “
Too many outputs requested. Most likely cause is missing [] around left hand side that has a comma separated list expansion.
“. Reading back, it looks like another user has also mentioned this – pause(1) (shorter is possibly fine too) resolved the error.Hi, I was just attempting to control plot marker transparency as described in this tutorial but for a line object made using
plot3. It seems like there is no MarkerHandle object created when using plot3. Is that the case? No way to make transparent marker faces / edges on a 3D plot?
Thanks for making such a great resource.
@Collin – there is indeed a MarkerHandle property also for plot3, exactly the same as for plot. The property is simply hidden and not displayed when you run the get/set commands, but once you know that it exists you can use it just like any other property.
@Yair – Ah, I’ve figured out my problem. Or at least I’ve figured out how to avoid it. It seems that if you set LineStyle, Marker, MarkerSize, or any items of that nature using the line handle before using hLine.MarkerHandle, then MarkerHandle becomes inaccessible.
I’ve also noticed that none of the changes made using MarkerHandle are reflected by the line properties.
Hi all. Great post. I tried this with R2016b and ran into similar issues when trying to export, i.e. the transparency would be lost. I found that MATLAB’s scatter command does pretty much exactly what I wanted by setting the (mildly undocumented?) MarkerEdgeAlpha and MarkerFaceAlpha properties, as mentioned here. Then export_fig works its magic and everything looks great (even in pdf!). My code looked something like this:
Hope that helps!
“Throughout today, we’ve kept the default FaceColorType/EdgeColorType value of ‘truecolor’ (which is really the same as ‘truecoloralpha’ as far as I can tell, since both accept an alpha transparency value as the 4th color element).”
As far as I tested, the above is not true for R2016b. It seems that you need to set FaceColorType/EdgeColorType to ‘truecoloralpha’ in order to get transparency effect.
Hi Yair,
Thanks for this awesome post. I am currently using R2014b however I cannot even find the property of the marker’s handle.
My opengl setting is as follows:
I find it very annoying that even copying some tutorial lines into my matlab doesn’t help set the target transparent.
Do you have any suggestion for this situation? Many thanks in advance.
Best regards,
Da
@DaV – I suspect that you have some extra code between the line where you plot() the data and the line where you extract/update the
hMarkers
and in the meantime either the line or the markers were deleted.In any case, your code was buggy in the sense that EdgeColorData expects a uint8 column array of values (as explained in my posts).
The following code snippet should work as-is:
There is also a possibility that this does not work on R2014b, which was the first Matlab release to officially use the new graphics system (HG2). In this case, try it with a newer release if you can.
There is also the possibility that this is due to your use of OpenGL emulation mode (software=’true’). You should really try to update your graphics driver so that Matlab will use OpenGL hardware acceleration (software=’false’), because the new graphics engine relies on OpenGL hardware much more than the previous graphics system (HG1, used until R2014a).
@Yair,
Thanks a lot for the trouble shooting. I pasted your code into the command line, it works perfectly.
I wondered a bit as there were actually nothing different between the code and what I tried yesterday but the last line.
Lastly I found this would be the key:
I will try a 2016 release on another computer tomorrow. Many thanks for this post. An eye-opener 🙂
Da
I really liked this hidden feature, but as far as I can see, R2017a and R2017b (prerelease) do not support the alpha setting of Markers as in:
The markers turn red by this, but they are not transparent.
@Kouichi – I believe that you are mistaken: Depending on exactly which type of Markers you have, it is possible that you simply need to modify the EdgeColorData instead of FaceColorData, and/or to modify EdgeColorType/FaceColorType from their default value of ‘truecolor’ to ‘truecoloralpha’. You will then see the transparent markers nicely.
Is there also a hidden MarkerHandle or something similar for animatedline? Because I get the following error trying the same with animatedline:
No appropriate method, property, or field 'MarkerHandle' for class 'matlab.graphics.animation.AnimatedLine'.
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 that it enables the user to have the semi-transparent markers also appear in the legend.
@Peter – very nice, thanks for sharing.
It would be nice if you would cite a reference to this page in the File Exchange description text, and in your GitHub README.md file.
Hi all;
I am facing problems exporting such figures as a pdf/svg to modify it using illustrator, especially when I have multiple subplots!
could anyone help me with this?
Best,
Try to use the export_fig utility
the problem is once exporting either using saveas or print functions, the transparency is not saved and gives a full normal color image! Thanks.
Thanks Yair,
Still, have the same problem. export_fig is exporting the figure without applying the transparency to the markers. On the screen, I have a nice figure, but once exporting the figure I am loosing all. I played with the rendering options, didn’t see any change or improvement! any idea?
So try using the ScreenCapture utility. Note that it only generates bitmap sceenshots, not vectorized (PDF/EPS) ones.
This is awesome Yair.
However, now I’m wondering if it’s possible to change the marker of a specific subset of plotted points after they’ve already been plotted. For example, if I set x = [1:10] and y = [1:10], and I plot(x,y,’o’), is it possible to change the circles to triangles from x(2:4)?
@Tyler – you cannot do that on the plotted markers directly, but you could create the line with no markers, and then overlay it with 2 additional lines that have no line, just the markers. For example:
Hi, I used the suggested script on pc and worked fine. However, when I moved to mac the same script stop working, and I have not transparency gradient. Any help? Thanks,
@Hassan – check perhaps a different figure renderer is used on your two computers.
Hello, I successfully applied the transparency and color gradient to the markers. However, this works for me just with the filled (heavier) markers like ‘o’, not for the lighter markers like ‘.’ and ‘+’. Any idea on that?
My hunch is that the simpler markers are implemented as OpenGL primitives and these are not painted like the more complex markers and are therefore not as customizable.
Thanks a lot for the very useful hack. Do you know how one can do something similar to a bar chart? In other words what would be the equivalent for MarkerHandler in a bar chart?
Thanks a lot
@Antonius – the corresponding internal objects in a bar chart are
hBarChart.Edge
andhBarChart.Face
.Also see related:
* http://undocumentedmatlab.com/blog/bar-plot-customizations
* http://undocumentedmatlab.com/blog/customizing-histogram-plots
I tried using hBarChart.Face to change the colors of the bars, but it did not work. I do not get any errors, but colors do not change. Here you are the command lines I used
@Antonius – try to add
drawnow; pause(0.1);
after the creation of the bar, before the use of the Face property.any hint on how this works with r2018b and beyond?
I was just trying this on a plot and get:
so I guess this ‘hack’ doesn’t work anymore. Is there a new way?
Of course it still works. Did I ever say “
h.FaceColorData
” (whereh
is the plot return handle) anywhere in my post? Read the post text carefully and try the code snippets one by one.ok, shame on me Yair, obviously it wasn’t the plot handle, might have been too late. I had another look and of course you’re right, it works.
Peter Rochford’s function which was an implementation of this didn’t work starting with r2018b anymore as he writes at the file exchange
https://www.mathworks.com/matlabcentral/fileexchange/65194-peterrochford-markertransparency
The comment of Arnold there is weird though. Adding a pause in front of setting the alpha value makes it reliable again. I wrote a test for it and yes, reliably works with a pause. Very strange.
The extra pause() (or drawnow) call forces Matlab’s graphic engine to flush (execute) any pending graphic rendering events in its graphics queue, thereby ensuring that when you set the transparency it “sticks”. Without the pause/drawnow, the graphics queue might reset the transparency after you have set it, depending on internal timings over which we have no control.
Related: http://undocumentedmatlab.com/blog/solving-a-matlab-hang-problem
Dear Yair,
I have the following code that worked for me in the past. I have nothing new except or using different dataset (the Matlab version is the same 2016a). But it is not working now!
I am getting a warning message after running the following command
Here are the full code lines that I used:
Any advice?
Thanks, HM
solved. the scatter plot was prepared for part of the full cell number!
Thank you for this post, it is very useful. It seems that when using plot3, if I have more than 25,000 points and I change my figure size or rotate the image, the MarkerHandle values revert back to the original settings and all color-information and/or transparency information is immediately reset. It is simple enough to reset the MarkerHandle properties following a viewpoint transformation but it is a bit of a pain, especially since I would like to explore the 3D point cloud using zoom and rotation. Have you discovered a similar issue and is there a workaround to this problem? The Matlab version I’m using is R2019a
Hello,
This post has been really useful to me. I just want to share a small trick. I have no idea whether it is reproducible or how it works, but it does the job for me (Win 10, R2019b).
When I use
plot
function, the transparency settings are always reset by any command related to the current figure.However, when I use
errorbar
the transparency settings are kept. So, I have been using errorbar instead of plot, with a ‘fake’ error vector, and a capsize equal to 0.E.g.:
And, all the more convenient, it works when actual error-bars are needed.
@Pierre – thanks for sharing this clever useful trick
This seems to have been disabled in the most recent version of Matlab (R2021b). When I use this method the hMarker.FaceColorData does change, but the markers are not made transparent. Any ideas?
Oliver – you probably forgot to update hMarkers.FaceColorType to ‘truecoloralpha‘:
Yair I have tried your code with trucoloralpha and the markers do not appear transparent in R2021b, same as for Oliver.
Dom – call drawnow *just before* you set hLine.MarkerHandle.FaceColorType to
'truecoloralpha'
.Also, you made a typo in your code: it’s truecoloralpha, not trucoloralpha.