目录
效果图
工具箱函数
输入参数:
输出参数
使用教程
案例1
案例3
案例4
案例5
案例6
案例7
案例8
扫一扫关注公众号:
今天教大家怎么把散点图替换成自己喜欢的图片,喜欢此推文的小伙伴们记得点赞+关注+分享!
效果图
看了slandarer和https://r-charts.com/miscellaneous/ggbernie/思路的启发,我也尝试写一个Matlab的图片散点图的教程。以下是R语言提供的一些案例。
首先介绍一下怎么把图片放到笛卡尔坐标系中。
clc;clear;close all; % 清除命令窗口,工作空间,关闭所有图形窗口
% 读取图像
[A,map,transparency]= imread('pic/猪猪侠/5.png');
% 根据图像类型进行转换
if isempty(map)
if size(A, 3) == 1
% 如果是灰度图像,转换为真彩色
imgRgb = repmat(A, [1 1 3]);
else
% 如果已经是真彩色图像,则不需要转换
imgRgb = A;
end
else
% 如果是索引色图像,转换为真彩色
imgRgb = ind2rgb(A, map);
end
% 反转图像和透明度,以适应坐标系
img = flipud(imgRgb);
AlphaImg = flipud(transparency);
hold on % 保持当前图像,以便在其上添加其他图形元素
% 在指定的x和y范围内显示图像
image([0.3 0.7],[0.3,0.7],img,"AlphaData", AlphaImg)
% 在(0.3, 0.3)和(0.7, 0.7)处绘制红色点
plot([0.3 0.7],[0.3 0.7],'ro','MarkerFaceColor','r','MarkerSize',16)
% 在点旁边添加文本标签
text(0.3,0.3,'(0.3,0,3)','Color','b','FontSize',14)
text(0.7,0.7,'(0.7,0,7)','Color','b','FontSize',14)
% 获取当前轴并进行设置
ax=gca;
axis square; % 设置坐标轴为正方形
ax.XLim=[0,1]; % 设置x轴的范围
ax.YLim=[0,1]; % 设置y轴的范围
ax.Color=[1,1,1]*0.85; % 设置轴的背景色
ax.LineWidth = 1; % 设置轴线宽度
% 其他轴设置
ax.XMinorTick = 'on'; % 打开X轴的次要刻度线
ax.YMinorTick = 'on'; % 打开Y轴的次要刻度线
ax.TickDir = 'out'; % 设置主要刻度线方向向外
ax.GridLineStyle = '-.'; % 设置网格线样式为虚线
ax.GridColor = 'k'; % 设置网格线颜色为黑色
ax.XGrid = 'on'; % 打开X轴的网格线
ax.YGrid = 'on'; % 打开Y轴的网格线
% 字体和标签设置
ax.FontSize = 14; % 设置字体大小
ax.FontName = 'Times New Roman'; % 设置字体
ax.XLabel.String = 'x'; % 设置X轴标签
ax.YLabel.String = 'y'; % 设置Y轴标签
先判断图片的类型,因为数据图片有真彩图片和索引图片,先把索引图片转换为真彩图片,然后flipud反转图像和透明度,反转的目的是为了将图片的坐标系转换成笛卡尔坐标系上。就可以利用image添加图像了,其中AlphaData是透明度属性。
然后准备一下图片数据https://www.stickpng.com/,下载好了保存到一个文件夹中,然后利用下面plotImageScatter绘图的工具函数。
工具箱函数
function Hdl=plotImageScatter(x, y, imgPath, coef)
% @author:猪猪侠
% @Email:2377389590@qq.com
% @WeChart:iDmatlab
% @公众号:好玩的Matlab
% plotImageScatter: 用图片替代散点图的散点
% 输入参数:
% x - x坐标向量
% y - y坐标向量
% imgPath - 图像路径
% coef - 控制图像大小的系数
% 读取图像和透明度数据
[A, map, transparency] = imread(imgPath);
% 根据图像类型进行转换
if isempty(map)
if size(A, 3) == 1
% 如果是灰度图像,转换为真彩色
imgRgb = repmat(A, [1 1 3]);
else
% 如果已经是真彩色图像,则不需要转换
imgRgb = A;
end
else
% 如果是索引色图像,转换为真彩色
imgRgb = ind2rgb(A, map);
end
% 反转图像和透明度,以适应坐标系
img = flipud(imgRgb);
AlphaImg = flipud(transparency);
% 获取当前坐标轴信息
ax = gca;
xLen = ax.XLim(2) - ax.XLim(1);
yLen = ax.YLim(2) - ax.YLim(1);
spectRatio = ax.PlotBoxAspectRatio;
% 根据坐标轴范围计算图像的宽度和高度
if xLen >= yLen
w = xLen;
h = yLen / spectRatio(2) * spectRatio(1);
else
w = xLen / spectRatio(1) * spectRatio(2);
h = yLen;
end
% 使用经验系数调整图像大小
coef = coef * 0.02; % 0.02为一个经验系数,没有特定的意义
% 使用循环绘制每个图像散点
for i = 1:length(x)
xPic = [-w/2, w/2] * coef(i) + x(i);
yPic = [-h/2, h/2] * coef(i) + y(i);
% 绘制图像
Hdl(i)=image(xPic, yPic, img, "AlphaData", AlphaImg);
end
end
其中函数参数:
输入参数:
-
x - x坐标向量
-
y - y坐标向量
-
imgPath - 图像路径
-
coef - 控制图像大小的系数
输出参数
-
Hdl为散点图像的句柄,可根据句柄获取和设置图像的参数。
使用教程
案例1
结合上一篇介绍的炫酷聚类散点图的ClusterViz类函数
clc;clear;close all; % 清除环境
% 生成随机坐标
num_points = 20;
theta = 2 * pi * rand(1, num_points);
r = sqrt(rand(1, num_points));
x = r .* cos(theta);
y = r .* sin(theta);
% 绘制散点图
sh1=scatter(x, y,'filled','CData',[0.1,0.1,0.1],'MarkerFaceAlpha',0.5,'MarkerEdgeColor','none','Marker','o');
hold on
coef=ones(1,length(x))*8;
plotImageScatter(x, y, 'pic/其他图片/1.png', coef); % 调用函数来绘制图像散点图
viz1 = ClusterViz(sh1, [x;y]');
viz1.PlotTypeState='on';
viz1.LineStyle='-';
viz1.clusterViz();
hold on % 保持当前图形
ax=gca;
% 设置轴属性
ax.XLim=[-1.5,1.5];
ax.YLim=[-1.5,1.5];
ax.LineWidth = 1;
ax.XMinorTick = 'on';
ax.YMinorTick = 'on';
ax.TickDir = 'in';
ax.GridLineStyle = '-.';
ax.GridColor = 'k';
ax.XGrid = 'on';
ax.YGrid = 'on';
ax.FontSize = 14;
ax.FontName = 'Times New Roman';
ax.XLabel.String = 'x';
ax.YLabel.String = 'y';
案例2
这个也是结合上一篇炫酷聚类散点图怎么绘制椭圆置信区间。
clc;clear;close all; % 清空命令窗口、清除所有变量和关闭所有图窗
% 创建随机数据点,并添加噪声
data=repmat([2 2],50,1) + randn(50,2)*[1 .5; 0 1.32];
x=data(:,1); % x坐标
y=data(:,2); % y坐标
% 生成随机大小因子
bigness=rand(1,length(x))*10;
subplot(1,2,1) % 创建一个1行2列的子图,并选择第一个
hold on % 保持当前图
sh1=scatter(x,y,bigness*50,'filled','CData',[1,0.5,0.8],'MarkerFaceAlpha',0.5,'MarkerEdgeColor','none','Marker','o');
confidenceLevel=0.95;
ell1 = ConfidenceEllipse(sh1,[x,y], confidenceLevel);
ell1.PlotType = 'fill';
ell1.Color=[0.9,0.5,0];
ell1.plotEllipse();
viz1 = ClusterViz(sh1, [x,y]);
viz1.PlotTypeState='off';
viz1.Color=[1,0.5,0.8];
viz1.LineStyle='-';
viz1.clusterViz();
% 设置第一个子图的轴属性
ax=gca;
ax.XLim=[-1,4];
ax.YLim=[-2,6];
ax.LineWidth=1; %线粗
ax.Box='on';% 关闭显示坐标区轮廓
ax.XMinorTick='on';%打开X轴的次要刻度线
ax.YMinorTick='on';%打开Y轴的次要刻度线
ax.TickDir='in';% 设置主要刻度线方向向外
ax.GridLineStyle='-.'; % 设置网格线样式为虚线
ax.GridColor='k'; % 设置网格线颜色为黑色
ax.XGrid='on'; % 打开X网格线
ax.YGrid='on'; % 打开Y网格线
ax.FontSize=14;% 字体大小设置14
ax.FontName='Times New Roman';%时代新罗马字体
ax.XLabel.String='x';% 设置X轴标签
ax.YLabel.String='y';% 设置Ys轴标签
subplot(1,2,2) % 选择第二个子图
hold on % 保持当前图
coef=bigness; % 设置图像大小
coef=coef*5; % 0.02是一个经验系数
plotImageScatter(x, y, 'pic/猪猪侠/5.png', coef); % 调用函数来绘制图像散点图
plot(x,y,'o','color','none') % 画出数据点
ell1 = ConfidenceEllipse(sh1,[x,y], confidenceLevel);
ell1.PlotType = 'fill';
ell1.plotEllipse();
viz1 = ClusterViz(sh1, [x,y]);
viz1.PlotTypeState='off';
viz1.Color=[1,0.5,0.8];
viz1.LineStyle='-';
viz1.clusterViz();
% 获取当前子图的轴
ax=gca;
% 设置第二个子图的轴属性
ax.XLim=[-1,4];
ax.YLim=[-2,6];
ax.LineWidth=1; %线粗
ax.Box='on';% 关闭显示坐标区轮廓
ax.XMinorTick='on';%打开X轴的次要刻度线
ax.YMinorTick='on';%打开Y轴的次要刻度线
ax.TickDir='in';% 设置主要刻度线方向向外
ax.GridLineStyle='-.'; % 设置网格线样式为虚线
ax.GridColor='k'; % 设置网格线颜色为黑色
ax.XGrid='on'; % 打开X网格线
ax.YGrid='on'; % 打开Y网格线
ax.FontSize=14;% 字体大小设置14
ax.FontName='Times New Roman';%时代新罗马字体
ax.XLabel.String='x';% 设置X轴标签
ax.YLabel.String='y';% 设置Ys轴标签
案例3
这也是结合炫酷的聚类散点图综合绘图。
clc; clear; close all;
d1=repmat([2 2],30,1) + randn(30,2)*[1 .5; 0 1.32];
d2=repmat([9 1],30,1) + randn(30,2)*[1.4 0.2; 0 0.98];
d3=repmat([6 8],30,1) + randn(30,2)*[1 0.5; 0 1.7];
d4=repmat([9 5],30,1) + randn(30,2)*[1 0.7; 0.5 2];
sh1=scatter(d1(:,1), d1(:,2),'filled','CData',[1,1,0],'MarkerFaceAlpha',0,'MarkerEdgeColor','none','Marker','o');
hold on
confidenceLevel=0.95;
ell1 = ConfidenceEllipse(sh1,d1, confidenceLevel);
ell1.PlotType = 'fill';
ell1.plotEllipse();
coef=ones(1,length(d1))*8;
plotImageScatter(d1(:,1), d1(:,2), 'pic/猪猪侠/2.png', coef); % 调用函数来绘制图像散点图
sh2=scatter(d2(:,1), d2(:,2),'filled','CData',[0,1,1],'MarkerFaceAlpha',0,'MarkerEdgeColor','none','Marker','o');
viz2 = ClusterViz(sh2, d2);
viz2.PlotType='fill';
viz2.clusterViz();
coef=ones(1,length(d2))*3;
plotImageScatter(d2(:,1),d2(:,2), 'pic/猪猪侠/3.png', coef); % 调用函数来绘制图像散点图
sh3=scatter(d3(:,1), d3(:,2),'filled','CData',[1,0.6471,0],'MarkerFaceAlpha',0,'MarkerEdgeColor','none','Marker','o');
ell3 = ConfidenceEllipse(sh3,d3, confidenceLevel);
ell3.PlotType = 'line';
ell3.LineStyle=':';
ell3.LineWidth=2;
ell3.FillAlpha=1;
ell3.plotEllipse();
coef=ones(1,length(d3))*3;
plotImageScatter(d3(:,1),d3(:,2), 'pic/猪猪侠/4.png', coef); % 调用函数来绘制图像散点图
sh4=scatter(d4(:,1), d4(:,2),'filled','CData',[1,0,0],'MarkerFaceAlpha',0,'MarkerEdgeColor','none','Marker','o');
ell4 = ConfidenceEllipse(sh4,d4, confidenceLevel);
ell4.PlotType = 'fill';
ell4.LineStyle='-';
ell4.LineWidth=1;
ell4.FillAlpha=0.1;
ell4.plotEllipse();
viz4 = ClusterViz(sh4, d4);
viz4.PlotTypeState='off';
viz4.Color=[0,1,1];
viz4.LineStyle='-';
viz4.clusterViz();
coef=ones(1,length(d4))*2;
plotImageScatter(d4(:,1),d4(:,2), 'pic/猪猪侠/5.png', coef); % 调用函数来绘制图像散点图
% 其他轴设置
ax = gca;
ax.LineWidth=1; %线粗
ax.Box='on';% 关闭显示坐标区轮廓
ax.XMinorTick='on';%打开X轴的次要刻度线
ax.YMinorTick='on';%打开Y轴的次要刻度线
ax.TickDir='in';% 设置主要刻度线方向向外
ax.GridLineStyle='-.'; % 设置网格线样式为虚线
ax.GridColor='k'; % 设置网格线颜色为黑色
ax.XGrid='on'; % 打开X网格线
ax.YGrid='on'; % 打开Y网格线
ax.FontSize=14;% 字体大小设置14
ax.FontName='Times New Roman';%时代新罗马字体
ax.XLabel.String='x';% 设置X轴标签
ax.YLabel.String='y';% 设置Ys轴标签
案例4
图片散点图基础绘制方法。
clc; clear; close all;
x = rand(1, 50) * 100;
y = rand(1, 50) * 100;
scatter(x, y, 'filled','CData',[1,0.5,0.8],'MarkerFaceAlpha',0,'MarkerEdgeColor','none','Marker','o');
hold on;
coef=rand(1,length(x))*10;
hArray=plotImageScatter(x, y, 'pic/头脑特工队/4.png', coef); % 调用函数来绘制图像散点图
% delete(hArray);
% 其他轴设置
ax = gca;
ax.LineWidth=1; %线粗
ax.Box='on';% 关闭显示坐标区轮廓
ax.XMinorTick='on';%打开X轴的次要刻度线
ax.YMinorTick='on';%打开Y轴的次要刻度线
ax.TickDir='in';% 设置主要刻度线方向向外
ax.GridLineStyle='-.'; % 设置网格线样式为虚线
ax.GridColor='k'; % 设置网格线颜色为黑色
ax.XGrid='on'; % 打开X网格线
ax.YGrid='on'; % 打开Y网格线
ax.FontSize=14;% 字体大小设置14
ax.FontName='Times New Roman';%时代新罗马字体
ax.XLabel.String='x';% 设置X轴标签
ax.YLabel.String='y';% 设置Ys轴标签
案例5
绘制曲线图+散点图片。
clc;clear;close all;
x=0:0.1:2*pi;
y=sin(x);
y2=cos(x);
plot(x,y,'-','LineWidth',2,'color',[0 0.6, 0.9])
hold on
coef=ones(1,length(x))*5;
plotImageScatter(x(1:5:end), y(1:5:end), 'pic/头脑特工队/4.png', coef); % 调用函数来绘制图像散点图
plot(x,y2,'r-','LineWidth',2)
xi=x(1:6:end);
yi=y2(1:6:end);
plotImageScatter(xi(1:2:end), yi(1:2:end), 'pic/头脑特工队/2.png', coef); % 调用函数来绘制图像散点图
plotImageScatter(xi(2:2:end), yi(2:2:end), 'pic/头脑特工队/6.png', coef); % 调用函数来绘制图像散点图
% 坐标系修饰
ax = gca;
ax.LineWidth=1; %线粗
ax.Box='on';% 关闭显示坐标区轮廓
ax.XMinorTick='on';%打开X轴的次要刻度线
ax.YMinorTick='on';%打开Y轴的次要刻度线
ax.TickDir='in';% 设置主要刻度线方向向内
ax.GridLineStyle='-.'; % 设置网格线样式为虚线
ax.GridColor='k'; % 设置网格线颜色为黑色
ax.XGrid='on'; % 打开X网格线
ax.YGrid='on'; % 打开Y网格线
ax.FontSize=14;% 字体大小设置14
ax.FontName='Times New Roman';%时代新罗马字体
ax.XLabel.String='x';% 设置X轴标签
ax.YLabel.String='y';% 设置Ys轴标签
案例6
绘制柱状图,并在柱状图添加散点图片。
clc;clear;close all;
% 输入数据
y = [1 2 3 4 5; 3 5 6 7 8; 6 8 9 10 11; 8 11 12 13 15];
x = 1:size(y,1);
% 创建柱状图并获取句柄
width =1;
bh = bar(x,y, 'BarWidth', width ); % 注意:BarWidth 设置为1,这是默认值
colorList=hsv(length(bh));
% 初始化顶点坐标存储变量
xTops = cell(size(y,2), 1);
yTops = cell(size(y,2), 1);
% 循环遍历每个柱状图对象(每一组)
for i = 1:length(bh)
xData = bh(i).XData; % x坐标(柱子组中心)
yData = bh(i).YData; % y坐标(柱子高度)
% 计算每根柱子的顶点x坐标(基于柱子中心)
xTops{i} =bh(i).XEndPoints;
% y坐标就是柱子的高度
yTops{i} = yData;% 现在 xTops 和 yTops 分别包含了各个柱子的顶部 x 和 y 坐标
bh(i).FaceColor=colorList(i,:);
bh(i).FaceAlpha=0.5;
bh(i).EdgeColor='none';
end
hold on
coef=ones(1,length(x))*4;
for i=1:size(y,2)
for j=1:size(y,1)
plotImageScatter( xTops{i}(j), yTops{i}(j)+0.6, ['pic/猪猪侠/',num2str(i),'.png'], coef); % 调用函数来绘制图像散点图
end
end
ax = gca; % 获取当前轴(axis)的句柄
ax.Box='off'; % 关闭轴边框
ax.LineWidth = 1; % 设置轴线宽度为1
ax.XMinorTick = 'off'; % 关闭X轴的次要刻度线
ax.YMinorTick = 'on'; % 打开Y轴的次要刻度线
ax.TickDir = 'out'; % 设置主要刻度线方向向外
ax.GridLineStyle = '-.'; % 设置网格线样式为虚线
ax.GridColor = 'k'; % 设置网格线颜色为黑色(注意注释中的"红色"是不准确的)
ax.XGrid = 'on'; % 打开X轴的网格线
ax.YGrid = 'on'; % 打开Y轴的网格线
ax.FontSize = 14; % 设置字体大小为14
ax.FontName = 'Times New Roman'; % 设置字体为Times New Roman
ax.XLabel.String = 'x'; % 设置X轴标签
ax.YLabel.String = 'y'; % 设置Y轴标签
案例7
利用散点图片绘制有趣的表白代码
案例8
绘制动态的图。
clc;clear;close all;
t=linspace(0,2*pi,200);
x=sin(t)*2;
y=cos(t)*2;
plotHdl=plot(x(1),y(1),'-','LineWidth',2,'color','none');
hold on
% 设置gca 属性
ax=gca;
ax.XLim=[-3,3];
ax.YLim=[-3,3];
ax.Box='off'; % 关闭轴边框
ax.LineWidth = 1; % 设置轴线宽度为1
ax.XMinorTick = 'on'; % 关闭X轴的次要刻度线
ax.YMinorTick = 'on'; % 打开Y轴的次要刻度线
ax.TickDir = 'in'; % 设置主要刻度线方向向外
ax.GridLineStyle = '-.'; % 设置网格线样式为虚线
ax.GridColor = 'k'; % 设置网格线颜色为黑色(注意注释中的"红色"是不准确的)
ax.XGrid = 'on'; % 打开X轴的网格线
ax.YGrid = 'on'; % 打开Y轴的网格线
ax.FontSize = 14; % 设置字体大小为14
ax.FontName = 'Times New Roman'; % 设置字体为Times New Roman
ax.XLabel.String = 'x'; % 设置X轴标签
ax.YLabel.String = 'y'; % 设置Y轴标签
coef=ones(1,length(x))*15;
Hdl1=plotImageScatter(x(1), y(1), 'pic/其他图片/ship1.png', coef); % 调用函数来绘制图像散点图
Hdl2=plotImageScatter(x(1), y(1), 'pic/其他图片/ship2.png', coef); % 调用函数来绘制图像散点图
Hdl3=plotImageScatter(x(1), y(1), 'pic/其他图片/ship3.png', coef); % 调用函数来绘制图像散点图
startPosX=Hdl1(1).XData-x(1);
startPosY=Hdl1(1).YData-y(1);
% 循环生成动画帧并保存为GIF
gifFileName = 'example.gif';% 设置GIF文件名
for n = 1:length(x)
plotHdl.XData(n) = x(n);
plotHdl.YData(n) = y(n);
if mod(n - 1, 3) + 1==1
Hdl1.Visible='on';
Hdl2.Visible='off';
Hdl3.Visible='off';
elseif mod(n - 1, 3) + 1==2
Hdl1.Visible='off';
Hdl2.Visible='on';
Hdl3.Visible='off';
elseif mod(n - 1, 3) + 1==3
Hdl1.Visible='off';
Hdl2.Visible='off';
Hdl3.Visible='on';
end
Hdl1.XData(:)=startPosX+x(n);
Hdl1.YData(:)=startPosY+y(n);
Hdl2.XData(:)=startPosX+x(n);
Hdl2.YData(:)=startPosY+y(n);
Hdl3.XData(:)=startPosX+x(n);
Hdl3.YData(:)=startPosY+y(n);
drawnow
pause(0.01);
% 获取当前帧
frame = getframe(gcf);
% 将帧转换为索引图像和颜色图
[imind, cm] = rgb2ind(frame.cdata, 256);
% 写入GIF文件
if n == 1
imwrite(imind, cm, gifFileName, 'gif', 'Loopcount', inf, 'DelayTime', 0.1);
else
imwrite(imind, cm, gifFileName, 'gif', 'WriteMode', 'append', 'DelayTime', 0.1);
end
end