半透明标记在对数-对数散点图上的应用

5
我一直在尝试在对数-对数散点图上获得半透明的圆形标记。MATLAB自带的scatter绘图函数不会产生半透明标记(请参见下面的评论),因此我正在使用这个很棒的工具scatter_patches来解决问题,它来自于Central File Exchange,而且它运行得非常好:
然而,我在将该代码适应于对数-对数散点图时遇到了问题。为了使用这个程序获得对数-对数散点图,我需要解决两个问题:
1. 将坐标轴改为对数刻度。这可以通过在第61行后添加以下内容来实现:
set(cax, 'XScale', 'log'); 
set(cax, 'YScale', 'log'); 

这将生成正确的对数刻度和网格点。
2. 但是,在我修复1之后,我的图中标记的大小不均匀。在对数图上,轴的较低值区域被放大。在scatter_patches图中,轴下侧的标记较大,而它们朝着轴的较高值侧变小。因此,整个图上的标记大小并不相同。我尝试在第221-222行使用log10(cSize)代替cSize,但这只减小了最大和最小标记大小之间的差异。它没有在图中产生相同大小的标记。
如果有人知道我可能遗漏了什么,请分享。
非常感谢任何帮助。

你尝试过使用Matlab的散点图set(hadle_to_scatterplot,'MarkerFaceColor','None')吗?似乎scatter_patches创建了一个圆圈而不是标记。 - Crowley
我已经尝试过了。将“MarkerFaceColor”设置为“None”等同于将透明度设置为100%。但是,我想控制透明度。如果存在像“MarkerFaceAlphaValue”这样的属性,则可以将透明度设置为任意值。但是,这样的属性不存在。scatter_patches使用补丁代替标记;因此可以设置FaceAlphaValue。该程序还允许创建其他形状,而不仅仅是圆形。该程序在线性图上运行非常好。对于对数图,需要进行一些更改。 - r2d2
我认为这篇文章会对你有兴趣。你尝试过在这里添加一个exp()吗:set(patchObjects(i), 'XData', cSize * sin(patchSpec) / ptsPerXUnit + xs(i)); set(patchObjects(i), 'YData', cSize * cos(patchSpec) / ptsPerYUnit + ys(i));像这样set(patchObjects(i), 'XData', cSize * exp(sin(patchSpec))/ ptsPerXUnit + xs(i));但我没有尝试过! - obchardon
更新:类似于这样:set(patchObjects(i), 'XData', exp(cSize * sin(patchSpec)/ ptsPerXUnit + xs(i)));,对于YData也是一样的。 - obchardon
3个回答

6
自从 Matlab R2014b 以来,事情变得非常简单。不需要从文件交换中获取任何附加功能,只需使用一些未记录的功能即可。基本思路是获取标记的隐藏句柄,并在EdgeColorData中的最后一个值上应用小于1的值,以实现所需的透明度。
下面开始:
%// 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] ); 

enter image description here


你的方法会将 hMarkers.EdgeColorData 的维度从 1x1x3 改变为 1x1x4,其中 'layers' 分别代表通道红、绿、蓝和透明度吗?换句话说,可以假设大小为 M x N x 4uint8 数组表示宽度为 M 像素、高度为 N 像素的纹理映射,并定义了每个像素的颜色和透明度吗? - Crowley
1
@user164568 我有MATLAB 2011b,所以我无法尝试。你尝试使用hMarkers.FaceColorData了吗? - Crowley
@Crowley 是的,完全正确。 - Robert Seifert
当然不是,你需要使用FaceColorData属性。看一下我的编辑。 - Robert Seifert
@thewaywewalk 你的编辑效果非常好!非常感谢!这也在对数图上很有效。幸运的是,我有MATLAB 2015a。 - r2d2
显示剩余5条评论

1
如果有帮助的话,我编写了一组Matlab函数,用于在图表和图例中创建半透明标记。这些文件可以从MATLAB Central获取,称为MarkerTransparency包。下载中包含如何使用这些函数的几个示例,并且GitHub上也有一个Wiki页面。该软件包的主要优点是它使用户能够在图例中看到半透明标记。虽然这些函数尚未针对散点图进行测试,但可能很容易地进行调整以满足您的需求。

0

在第192行将该行更改为:

hh(end+1) = patch( exp(cSize * sin(patchSpec) / ptsPerXUnit + xs(i)), exp(cSize * cos(patchSpec) / ptsPerYUnit + ys(i)), cColor, cPatchArgs{:});,它就可以工作了。

我只是添加了一个exp()

在第222和223行执行相同的操作以确保!

像魅力一样工作,Anindya ;).


我的图是在log10刻度上的。所以我使用了hh(end+1) = patch( 10.^((cSize * sin(patchSpec) / ptsPerXUnit + xs(i))./10), 10.^((cSize * cos(patchSpec) / ptsPerYUnit + ys(i))./10), cColor, cPatchArgs{:}); 这肯定会产生相同大小的圆。然而,我的图看起来与MATLAB的scatterplot函数产生的图不同。请参见此处:http://imgur.com/21yM6hY - r2d2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接