MATLAB | 绘图复刻(十四) | 右侧对齐桑基图,及工具函数SSankey更新

hey 真的好久不见了,本期既是一期绘图复刻教程,也是我写的工具函数的版本更新,本期复刻的图片来自《Nature》:

  • Elmarakeby, H.A., Hwang, J., Arafeh, R. et al. Biologically informed deep neural network for prostate cancer discovery. Nature 598, 348–352 (2021). https://doi.org/10.1038/s41586-021-03922-4

绘图复刻效果如下:

本文所用工具函数的基本使用教程可参见以下文章:
https://blog.csdn.net/slandarer/article/details/130430147

该文章仅展示工具函数基本使用方法,本文需要用到文末2.0.0版本工具函数

该文章仅展示工具函数基本使用方法,本文需要用到文末2.0.0版本工具函数



绘图复刻教程部分

0 数据

本文所使用的数据大概长这样,存储在.mat文件中:

load('natureRandData.mat')

该文件依旧可以在文末所示仓库获取,当然这组数据是通过以下方式随机生成的,直接复制以下代码也是可以的:

% rng(5)
% SourceValue=[60,40,30];
% LayerNum=[3,10,10,10,10,10,6,1];
% links{1,3}='';
% for k=1
%     TargetValue=zeros(1,LayerNum(k+1));
%     for i=1:LayerNum(k)
%         tValue=randi([1,13],[1,LayerNum(k+1)]);
%         tValue=tValue./sum(tValue).*SourceValue(i);
%         for j=1:LayerNum(k+1)
%             TargetValue(j)=TargetValue(j)+tValue(j);
%             if tValue(j)>eps
%                 tLen=size(links,1);
%                 links{tLen+1,1}=[char(64+k),num2str(i)];
%                 links{tLen+1,2}=[char(64+k+1),num2str(j)];
%                 links{tLen+1,3}=tValue(j);
%             end
%         end
%     end
%     SourceValue=TargetValue;
% end
% links(1,:)=[];
% tResidual=0;
% for k=2:5
%     [~,tindex]=sort(rand([1,10]));
%     for i=1:10
%         tLen=size(links,1);
%         TargetValue(tindex(i))=SourceValue(i);
%         links{tLen+1,1}=[char(64+k),num2str(i)];
%         links{tLen+1,2}=[char(64+k+1),num2str(tindex(i))];
%         links{tLen+1,3}=SourceValue(i);
%     end
%     for i=1:10
%         tLen=size(links,1);
%         links{tLen+1,1}=['Residual-',char(64+k)];
%         links{tLen+1,2}=[char(64+k+1),num2str(tindex(i))];
%         tValue=rand([1,1])*20./(k.^1);
%         links{tLen+1,3}=tValue;
%         if k==2,tResidual=tResidual+tValue;end
%         if k==5,TargetValue(i)=TargetValue(i)+tValue;end
%     end
%     SourceValue=TargetValue;
% end
% k=1;tValue=randi([1,13],[1,3]);
% for i=1:3
%     tLen=size(links,1);
%     links{tLen+1,1}=[char(64+k),num2str(i)];
%     links{tLen+1,2}=['Residual-',char(64+k+1)];
%     links{tLen+1,3}=tValue(i)./sum(tValue).*tResidual;
% end
% for k=6
%     TargetValue=zeros(1,LayerNum(k+1));
%     for i=1:LayerNum(k)
%         tValue=randi([1,13],[1,LayerNum(k+1)]);
%         tValue=tValue./sum(tValue).*SourceValue(i);
%         for j=1:LayerNum(k+1)
%             TargetValue(j)=TargetValue(j)+tValue(j);
%             if tValue(j)>eps
%                 tLen=size(links,1);
%                 links{tLen+1,1}=[char(64+k),num2str(i)];
%                 links{tLen+1,2}=[char(64+k+1),num2str(j)];
%                 links{tLen+1,3}=tValue(j);
%             end
%         end
%     end
%     SourceValue=TargetValue;
% end
% k=7;
% for i=1:LayerNum(end-1)
%     tLen=size(links,1);
%     links{tLen+1,1}=[char(64+k),num2str(i)];
%     links{tLen+1,2}=' ';
%     links{tLen+1,3}=SourceValue(i);
% end
% save natureRandData.mat links

1 配色

配色数据就是随便找个颜色提取器提取的论文原图:

CList1=[233,163,117; 150,209,224; 78 ,115,180]./255;
CList2=[149, 77, 85; 182, 85, 90; 208, 91, 94;208, 91, 94; 245,124,112; 252,150,128;252,173,151; 253,196,176; 253,217,203;254,236,228; 230,230,230]./255;

2 基础绘图

% 创建桑基图对象(Create a Sankey diagram object)
SK=SSankey(links(:,1),links(:,2),links(:,3));% % 类似于向右侧对齐
% SK.LayerOrder='reverse';% 修改链接颜色渲染方式(Set link color rendering method)
% 'left'/'right'/'interp'(default)/'map'/'simple'
SK.RenderingMethod='left';  % 修改对齐方式(Set alignment)
% 'up'/'down'/'center'(default)
SK.Align='center';% 修改文本位置(Set Text Location)
% 'left'(default)/'right'/'top'/'center'/'bottom'
SK.LabelLocation='right';% 设置缝隙占比(Separation distance proportion)
SK.Sep=0.02;
% SK.Sep=[.08,.04,.02,.05,.05,.06,.07];% 设置方块占比(Set the scale of blocks)
% BlockScale>0 & BlockScale<1
SK.BlockScale=.16;% 设置颜色(Set color)
SK.ColorList=[CList1;CList2(1:11,:)CList2(1:11,:)CList2(1:11,:)CList2(1:11,:)CList2(1:10,:)CList2(1:6,:)CList2(1,:)];% 开始绘图(Start drawing)
SK.draw()


3 右侧对齐

我们发现此时有的Residual方块由于左侧没有方块会被排列在最左侧,这样会比较混乱,此时选择将LayerOrder设置为反方向(此操作要在SK.draw()之前):

% 类似于向右侧对齐
SK.LayerOrder='reverse';


4 自定义缝隙比例

我们发现由于流入流出数据不相等,越往右侧整体会越窄,而原图基本上是两端对齐的,因此我们可以调整每一层的缝隙占比,比如(此操作要在SK.draw()之前):

% 设置缝隙占比(Separation distance proportion)
% SK.Sep=0.02;
SK.Sep=[.08,.04,.02,.05,.05,.06,.07];


5 节点方块修饰

加个白框:

for i=1:SK.BNSK.setBlock(i,'EdgeColor',[1,1,1],'LineWidth',1)
end


6 添加标签

就直接用text硬画,第i层的横坐标就是i,而宽度是SK.BlockScale,因此比较容易找到每层的X方向中点:

FontCell={'FontSize',22,'FontName','Times New Roman','HorizontalAlignment','center','VerticalAlignment','bottom'};
for i=2:SK.LN-1text(i+SK.BlockScale/2,min(min(SK.LayerPos(:,3:4))),['H',num2str(i-1)],FontCell{:})
end
text(1+SK.BlockScale/2,min(min(SK.LayerPos(:,3:4))),'Input',FontCell{:})
text(8+SK.BlockScale/2,min(min(SK.LayerPos(:,3:4))),'OutCome',FontCell{:})


绘图复刻完整代码

% -----------------------------------------------------+
% @author  | slandarer                                 |
% -----------------------------------------------------+
% 复刻自   | www.nature.com/articles/s41586-021-03922-4 |
% -----------------------------------------------------+figure('Name','nature sankey demo','Units','normalized','Position',[.05,.2,.9,.56])
clc;clear;%% 配色 ===================================================================
CList1=[233,163,117; 150,209,224; 78 ,115,180]./255;
CList2=[149, 77, 85; 182, 85, 90; 208, 91, 94;208, 91, 94; 245,124,112; 252,150,128;252,173,151; 253,196,176; 253,217,203;254,236,228; 230,230,230]./255;
%% 随意构造数据 ============================================================
load('natureRandData.mat')%% 绘图主要代码 ============================================================
% 创建桑基图对象(Create a Sankey diagram object)
SK=SSankey(links(:,1),links(:,2),links(:,3));% 类似于向右侧对齐
SK.LayerOrder='reverse';% 修改链接颜色渲染方式(Set link color rendering method)
% 'left'/'right'/'interp'(default)/'map'/'simple'
SK.RenderingMethod='left';  % 修改对齐方式(Set alignment)
% 'up'/'down'/'center'(default)
SK.Align='center';% 修改文本位置(Set Text Location)
% 'left'(default)/'right'/'top'/'center'/'bottom'
SK.LabelLocation='right';% 设置缝隙占比(Separation distance proportion)
% SK.Sep=0.02;
SK.Sep=[.08,.04,.02,.05,.05,.06,.07];% 设置方块占比(Set the scale of blocks)
% BlockScale>0 & BlockScale<1
SK.BlockScale=.16;% 设置颜色(Set color)
SK.ColorList=[CList1;CList2(1:11,:)CList2(1:11,:)CList2(1:11,:)CList2(1:11,:)CList2(1:10,:)CList2(1:6,:)CList2(1,:)];% 开始绘图(Start drawing)
SK.draw()
%% 修饰 ===================================================================for i=1:SK.BNSK.setBlock(i,'EdgeColor',[1,1,1],'LineWidth',1)
end
FontCell={'FontSize',22,'FontName','Times New Roman','HorizontalAlignment','center','VerticalAlignment','bottom'};
for i=2:SK.LN-1text(i+SK.BlockScale/2,min(min(SK.LayerPos(:,3:4))),['H',num2str(i-1)],FontCell{:})
end
text(1+SK.BlockScale/2,min(min(SK.LayerPos(:,3:4))),'Input',FontCell{:})
text(8+SK.BlockScale/2,min(min(SK.LayerPos(:,3:4))),'OutCome',FontCell{:})

工具函数完整代码

classdef SSankey < handle
% Copyright (c) 2023, Zhaoxu Liu / slandarer
% =========================================================================
% @author : slandarer
% =========================================================================
% # update 2.0.0(2024-02-04)
% see natureSankeyDemo1.m
%
% + 层向右对齐(Align layers to the right)
%   try : obj.LayerOrder='reverse';
%
% + 单独调整每层间隙大小(Adjust the Sep size of each layer separately)
%   try : obj..Sep=[.2,.06,.05,.07,.07,.08,.15];
% propertiesSource;Target;Value;SourceInd;TargetInd;Layer;LayerPos;LayerOrder='normal';AdjMat;BoolMat;RenderingMethod='interp'  % 'left'/'right'/'interp'/'map'/'simple'LabelLocation='left'      % 'left'/'right'/'top'/'center'/'bottom'Align='center'            % 'up'/'down'/'center'BlockScale=0.05;          %  BlockScale>0 ! !Sep=0.05;                 %  Sep>=0 ! !NodeList={};ColorList=[[65,140,240;252,180,65;224,64,10;5,100,146;191,191,191;26,59,105;255,227,130;18,156,221;202,107,75;0,92,219;243,210,136;80,99,129;241,185,168;224,131,10;120,147,190]./255;[127,91,93;187,128,110;197,173,143;59,71,111;104,95,126;76,103,86;112,112,124;72,39,24;197,119,106;160,126,88;238,208,146]./255];BlockHdl;LinkHdl;LabelHdl;ax;Parent;BN;LN;VN;TotalLen;SepLen;arginList={'RenderingMethod','LabelLocation','BlockScale',...'Sep','Align','ColorList','Parent','NameList'}end
% 构造函数 =================================================================methodsfunction obj=SSankey(varargin)% 获取基本数据 -------------------------------------------------if isa(varargin{1},'matlab.graphics.axis.Axes')obj.ax=varargin{1};varargin(1)=[];else  endobj.Source=varargin{1};obj.Target=varargin{2};obj.Value=varargin{3};varargin(1:3)=[];% 获取其他信息 -------------------------------------------------for i=1:2:(length(varargin)-1)tid=ismember(obj.arginList,varargin{i});if any(tid)obj.(obj.arginList{tid})=varargin{i+1};endendif isempty(obj.ax)&&(~isempty(obj.Parent)),obj.ax=obj.Parent;endif isempty(obj.ax),obj.ax=gca;endobj.ax.NextPlot='add';% 基本数据预处理 -----------------------------------------------if isempty(obj.NodeList)obj.NodeList=[obj.Source;obj.Target];obj.NodeList=unique(obj.NodeList,'stable');endobj.BN=length(obj.NodeList);if length(obj.NodeList)>size(obj.ColorList,1)obj.ColorList=[obj.ColorList;rand(length(obj.NodeList),3).*.7];endobj.VN=length(obj.Value);% 坐标区域基础设置 ---------------------------------------------obj.ax.YDir='reverse';obj.ax.XColor='none';obj.ax.YColor='none';end
% 绘图函数 =================================================================function draw(obj)% 生成整体邻接矩阵 ---------------------------------------------obj.AdjMat=zeros(obj.BN,obj.BN);for i=1:length(obj.Source)obj.SourceInd(i)=find(strcmp(obj.Source{i},obj.NodeList));obj.TargetInd(i)=find(strcmp(obj.Target{i},obj.NodeList));obj.AdjMat(obj.SourceInd(i),obj.TargetInd(i))=obj.Value{i};endobj.BoolMat=abs(obj.AdjMat)>0;% 计算每个对象位于的层、每层方块长度、每个方块位置 ----------------if strcmp(obj.LayerOrder,'normal')obj.Layer=zeros(obj.BN,1);obj.Layer(sum(obj.BoolMat,1)==0)=1;startMat=diag(obj.Layer);for i=1:(obj.BN-1)tLayer=(sum(startMat*obj.BoolMat^i,1)>0).*(i+1);obj.Layer=max([obj.Layer,tLayer'],[],2);endelseobj.Layer=zeros(obj.BN,1);obj.Layer(sum(obj.BoolMat,2)==0)=-1;startMat=diag(obj.Layer);for i=1:(obj.BN-1)tLayer=(sum(startMat*(obj.BoolMat.')^i,1)<0).*(-i-1);obj.Layer=min([obj.Layer,tLayer'],[],2);endobj.Layer=obj.Layer-min(obj.Layer)+1;endobj.LN=max(obj.Layer);obj.TotalLen=max([sum(obj.AdjMat,1).',sum(obj.AdjMat,2)],[],2);obj.SepLen=max(obj.TotalLen).*obj.Sep;obj.LayerPos=zeros(obj.BN,4);for i=1:obj.LNtBlockInd=find(obj.Layer==i);tBlockLen=[0;cumsum(obj.TotalLen(tBlockInd))];tY1=tBlockLen(1:end-1)+(0:length(tBlockInd)-1).'.*obj.SepLen(min(i,length(obj.Sep)));tY2=tBlockLen(2:end)+(0:length(tBlockInd)-1).'.*obj.SepLen(min(i,length(obj.Sep)));obj.LayerPos(tBlockInd,3)=tY1;obj.LayerPos(tBlockInd,4)=tY2;% for j=1:length(tY2)%     plot([i,i],[tY1(j),tY2(j)],'LineWidth',2)% endendobj.LayerPos(:,1)=obj.Layer;obj.LayerPos(:,2)=obj.Layer+obj.BlockScale;% 根据对齐方式调整Y坐标 -----------------------------------------tMinY=min(obj.LayerPos(:,3));tMaxY=max(obj.LayerPos(:,4));for i=1:obj.LNtBlockInd=find(obj.Layer==i);tBlockPos3=obj.LayerPos(tBlockInd,3);tBlockPos4=obj.LayerPos(tBlockInd,4);switch obj.Aligncase 'up'case 'down'obj.LayerPos(tBlockInd,3)=obj.LayerPos(tBlockInd,3)+tMaxY-max(tBlockPos4);obj.LayerPos(tBlockInd,4)=obj.LayerPos(tBlockInd,4)+tMaxY-max(tBlockPos4);case 'center'obj.LayerPos(tBlockInd,3)=obj.LayerPos(tBlockInd,3)+...min(tBlockPos3)/2-max(tBlockPos4)/2+tMinY/2-tMaxY/2;obj.LayerPos(tBlockInd,4)=obj.LayerPos(tBlockInd,4)+...min(tBlockPos3)/2-max(tBlockPos4)/2+tMinY/2-tMaxY/2;endend% 绘制连接 -----------------------------------------------------for i=1:obj.VNtSource=obj.SourceInd(i);tTarget=obj.TargetInd(i);tS1=sum(obj.AdjMat(tSource,1:(tTarget-1)))+obj.LayerPos(tSource,3);tS2=sum(obj.AdjMat(tSource,1:tTarget))+obj.LayerPos(tSource,3);tT1=sum(obj.AdjMat(1:(tSource-1),tTarget))+obj.LayerPos(tTarget,3);tT2=sum(obj.AdjMat(1:tSource,tTarget))+obj.LayerPos(tTarget,3);if isempty(tS1),tS1=0;endif isempty(tT1),tT1=0;endtX=[obj.LayerPos(tSource,1),obj.LayerPos(tSource,2),obj.LayerPos(tTarget,1),obj.LayerPos(tTarget,2)];qX=linspace(obj.LayerPos(tSource,1),obj.LayerPos(tTarget,2),200);qT=linspace(0,1,50);qY1=interp1(tX,[tS1,tS1,tT1,tT1],qX,'pchip');qY2=interp1(tX,[tS2,tS2,tT2,tT2],qX,'pchip');XX=repmat(qX,[50,1]);YY=qY1.*(qT'.*0+1)+(qY2-qY1).*(qT');MeshC=ones(50,200,3);switch obj.RenderingMethodcase 'left'MeshC(:,:,1)=MeshC(:,:,1).*obj.ColorList(tSource,1);MeshC(:,:,2)=MeshC(:,:,2).*obj.ColorList(tSource,2);MeshC(:,:,3)=MeshC(:,:,3).*obj.ColorList(tSource,3);case 'right'MeshC(:,:,1)=MeshC(:,:,1).*obj.ColorList(tTarget,1);MeshC(:,:,2)=MeshC(:,:,2).*obj.ColorList(tTarget,2);MeshC(:,:,3)=MeshC(:,:,3).*obj.ColorList(tTarget,3);case 'interp'MeshC(:,:,1)=repmat(linspace(obj.ColorList(tSource,1),obj.ColorList(tTarget,1),200),[50,1]);MeshC(:,:,2)=repmat(linspace(obj.ColorList(tSource,2),obj.ColorList(tTarget,2),200),[50,1]);MeshC(:,:,3)=repmat(linspace(obj.ColorList(tSource,3),obj.ColorList(tTarget,3),200),[50,1]);case 'map'MeshC=MeshC(:,:,1).*obj.Value{i};case 'simple'MeshC(:,:,1)=MeshC(:,:,1).*.6;MeshC(:,:,2)=MeshC(:,:,2).*.6;MeshC(:,:,3)=MeshC(:,:,3).*.6;endobj.LinkHdl(i)=surf(obj.ax,XX,YY,XX.*0,'EdgeColor','none','FaceAlpha',.3,'CData',MeshC);end% 绘制方块 -----------------------------------------------------for i=1:obj.BNobj.BlockHdl(i)=fill(obj.ax,obj.LayerPos(i,[1,2,2,1]),...obj.LayerPos(i,[3,3,4,4]),obj.ColorList(i,:),'EdgeColor','none');end% 绘制文本 -----------------------------------------------------for i=1:obj.BNswitch obj.LabelLocationcase 'right'obj.LabelHdl(i)=text(obj.ax,obj.LayerPos(i,2),mean(obj.LayerPos(i,[3,4])),...[' ',obj.NodeList{i}],'FontSize',15,'FontName','Times New Roman','HorizontalAlignment','left');case 'left'obj.LabelHdl(i)=text(obj.ax,obj.LayerPos(i,1),mean(obj.LayerPos(i,[3,4])),...[obj.NodeList{i},' '],'FontSize',15,'FontName','Times New Roman','HorizontalAlignment','right');case 'top'obj.LabelHdl(i)=text(obj.ax,mean(obj.LayerPos(i,[1,2])),obj.LayerPos(i,3),...obj.NodeList{i},'FontSize',15,'FontName','Times New Roman','HorizontalAlignment','center','VerticalAlignment','bottom');case 'center'obj.LabelHdl(i)=text(obj.ax,mean(obj.LayerPos(i,[1,2])),mean(obj.LayerPos(i,[3,4])),...obj.NodeList{i},'FontSize',15,'FontName','Times New Roman','HorizontalAlignment','center');case 'bottom'obj.LabelHdl(i)=text(obj.ax,mean(obj.LayerPos(i,[1,2])),obj.LayerPos(i,4),...obj.NodeList{i},'FontSize',15,'FontName','Times New Roman','HorizontalAlignment','center','VerticalAlignment','top');endend% -------------------------------------------------------------axis tight;help SSankeyend
% =========================================================================function setBlock(obj,n,varargin)set(obj.BlockHdl(n),varargin{:})endfunction setLink(obj,n,varargin)set(obj.LinkHdl(n),varargin{:})endfunction setLabel(obj,n,varargin)set(obj.LabelHdl(n),varargin{:})endfunction moveBlockY(obj,n,dy)obj.LayerPos(n,[3,4])=obj.LayerPos(n,[3,4])-dy;set(obj.BlockHdl(n),'YData',obj.LayerPos(n,[3,3,4,4]));switch obj.LabelLocationcase 'right',set(obj.LabelHdl(n),'Position',[obj.LayerPos(n,2),mean(obj.LayerPos(n,[3,4]))]);case 'left',set(obj.LabelHdl(n),'Position',[obj.LayerPos(n,1),mean(obj.LayerPos(n,[3,4]))]);case 'top',set(obj.LabelHdl(n),'Position',[mean(obj.LayerPos(n,[1,2])),obj.LayerPos(n,3)]);case 'center',set(obj.LabelHdl(n),'Position',[mean(obj.LayerPos(n,[1,2])),mean(obj.LayerPos(n,[3,4]))]);case 'bottom',set(obj.LabelHdl(n),'Position',[mean(obj.LayerPos(n,[1,2])),obj.LayerPos(n,4)]);endfor i=1:obj.VNtSource=obj.SourceInd(i);tTarget=obj.TargetInd(i);if tSource==n||tTarget==ntS1=sum(obj.AdjMat(tSource,1:(tTarget-1)))+obj.LayerPos(tSource,3);tS2=sum(obj.AdjMat(tSource,1:tTarget))+obj.LayerPos(tSource,3);tT1=sum(obj.AdjMat(1:(tSource-1),tTarget))+obj.LayerPos(tTarget,3);tT2=sum(obj.AdjMat(1:tSource,tTarget))+obj.LayerPos(tTarget,3);if isempty(tS1),tS1=0;endif isempty(tT1),tT1=0;endtX=[obj.LayerPos(tSource,1),obj.LayerPos(tSource,2),obj.LayerPos(tTarget,1),obj.LayerPos(tTarget,2)];qX=linspace(obj.LayerPos(tSource,1),obj.LayerPos(tTarget,2),200);qT=linspace(0,1,50);qY1=interp1(tX,[tS1,tS1,tT1,tT1],qX,'pchip');qY2=interp1(tX,[tS2,tS2,tT2,tT2],qX,'pchip');YY=qY1.*(qT'.*0+1)+(qY2-qY1).*(qT');set(obj.LinkHdl(i),'YData',YY);endendendend
% Copyright (c) 2023, Zhaoxu Liu / slandarer
% =========================================================================
% @author : slandarer
% -------------------------------------------------------------------------
end

以上已经是完整代码,对于工具函数2.0.0更新版,未经允许本代码请勿作商业用途,引用的话可以引用我file exchange上的链接,可使用如下格式:

Zhaoxu Liu / slandarer (2023). sankey plot (https://www.mathworks.com/matlabcentral/fileexchange/128679-sankey-plot), MATLAB Central File Exchange. 检索来源 2023/4/28.

若转载请保留以上file exchange链接及本文链接!!!!!

该工具可通过上述fileexchange链接获取,或者通过以下gitee仓库下载:

https://gitee.com/slandarer/matlab-sankey-diagram


对于绘图复刻以及.mat文件,可以去以下gitee仓库获取全部代码:

https://gitee.com/slandarer/PLTreprint/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/252558.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ideaIU-2023.2.1安装教程

ideaIU-2023.2.1安装教程 一、ideaIU-2023.2.1安装1.1 下载IdeaIU-2023.2.1安装包1.2 安装ideaIU-2023.2.1 二、ideaIU-2023.2.1激活 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 一、ideaIU-2023.2.1安装 1.1 下载IdeaIU-2023.2.1安装包…

LLM应用开发与落地:使用gradio十分钟搭建聊天UI

一、背景 如果你是做LLM应用开发的&#xff0c;特别是做后端开发&#xff0c;你一定会遇到怎么快速写一个聊天UI界面来调试prompt或agent的问题。这时候的你可能在苦恼中&#xff0c;毕竟react.js, next.js, css, html也不是每个人都那么熟练&#xff0c;对吧&#xff1f;即使…

性能实测:分布式存储 ZBS 与集中式存储 HDS 在 Oracle 数据库场景表现如何

作者&#xff1a;深耕行业的 SmartX 金融团队 金鑫 在金融客户的基础架构环境中&#xff0c;HDS 是一种被广泛使用的存储解决方案。作为集中式存储的代表之一&#xff0c;HDS 拥有高性能、高可用性和可扩展性的企业级存储特点&#xff0c;适用于实时数据处理、虚拟化和灾难备份…

【C语言】贪吃蛇 详解

该项目需要的技术要点 C语言函数、枚举、结构体、动态内存管理、预处理指令、链表、Win32API等。 由于篇幅限制 和 使知识模块化&#xff0c; 若想了解 使用到的 Win32API 的知识&#xff1a;请点击跳转&#xff1a;【Win32API】贪吃蛇会使用到的 Win32API 目录 1. 贪吃蛇游…

数据分析基础之《pandas(5)—文件读取与存储》

一、概述 1、我们的数据大部分存在于文件当中&#xff0c;所以pandas会支持复杂的IO操作&#xff0c;pandas的API支持众多文件格式&#xff0c;如CSV、SQL、XLS、JSON、HDF5 二、CSV 1、读取csv文件 read_csv(filepath_or_buffer, sep,, delimiterNone) 说明&#xff1a; fi…

Mac OS中创建适合网络备份的加密镜像文件:详细步骤与参数选择

这篇文章提供了在Mac OS中创建适合网络备份的加密镜像文件的详细步骤&#xff0c;同时探讨了在选择相关参数时的关键考虑因素&#xff0c;以确保用户能够安全、高效地存储和保护重要数据。 创建步骤 在Mac OS Monterey中&#xff0c;你可以使用“磁盘工具”&#xff08;Disk …

代码随想录算法训练营第25天 | 216.组合总和III ,17.电话号码的字母组合

回溯章节理论基础&#xff1a; https://programmercarl.com/%E5%9B%9E%E6%BA%AF%E7%AE%97%E6%B3%95%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html 216.组合总和III 题目链接&#xff1a;https://leetcode.cn/problems/combination-sum-iii/ 思路: 本题就是在[1,2,3,4,5,6,7,…

ElasticSearch查询语句用法

查询用法包括&#xff1a;match、match_phrase、multi_match、query_string、term 1.match 1.1 不同字段权重 如果需要为不同字段设置不同权重&#xff0c;可以考虑使用bool查询的should子句来组合多个match查询&#xff0c;并为每个match查询设置不同的权重 {"query&…

FANUC机器人开机时无法进入系统,示教器黑屏故障处理总结

FANUC机器人开机时无法进入系统&#xff0c;示教器黑屏故障处理总结 故障描述&#xff1a; FANUC机器人开机时&#xff0c;示教器在初始化时显示&#xff1a;EMAC initial call failed&#xff08;示教器上电时会进入boot画面&#xff0c;左上角会出现一些白色的英文提示&#…

SM2259XT量产工具修复金泰克固态硬盘29F01T2ALCQJ1颗粒开卡

在这里插入代码片前言 网心云用的固态硬盘突然坏了识别不了&#xff0c;磁盘管理、diskGenius、pe系统里均无法识别&#xff0c;查询发现可以用开卡工具修复&#xff0c;遂进行了一番折腾。 拆硬盘 如图硬盘是块金泰克240g容量的&#xff0c;拆开后找到主控芯片型号为SM2259…

关于RabbitMQ面试题汇总

什么是消息队列&#xff1f;消息队列有什么用&#xff1f; 消息队列是一种在应用程序之间传递消息的通信机制。它是一种典型的生产者-消费者模型&#xff0c;其中生产者负责生成消息并将其发送到队列中&#xff0c;而消费者则从队列中获取消息并进行处理。消息队列的主要目的是…

synchronized内部工作原理

作者简介&#xff1a; zoro-1&#xff0c;目前大二&#xff0c;正在学习Java&#xff0c;数据结构&#xff0c;javaee等 作者主页&#xff1a; zoro-1的主页 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01;&#x1f496;&#x1f496; synchronized内部工作原理 syn…

【AWS】step-functions服务编排

文章目录 step-functionsState machine typeStandard workflowsExpress workflows design skillsError handlingsaga Transaction processing控制分布式系统中的并发性 收费 作为AWS Serverless无服务器的一个重要一环 使用step-functions方法将 AWS 服务链接在一起 step-funct…

PySpark(二)RDD基础、RDD常见算子

目录 RDD RDD五大特性 RDD创建 RDD算子 常见的Transformation算子 map flatMap mapValues reduceByKey groupBy filter distinct union join intersection glom groupByKey groupByKey和reduceByKey的区别 ? sortBy sortByKey 常见的action算子 countByKey…

数据结构:单链表

文章目录 1. 单链表的概念及结构2. 单链表相关操作2.1 创建节点2.2 尾插2.3 打印2.4 头插2.5 尾删2.6 头删2.7 查找2.8 指定位置后插入2.9 指定位置前插入2.10 删除指定位置2.11 删除指定位置后的节点2.12 销毁单链表 3. 链表种类 1. 单链表的概念及结构 概念&#xff1a;链表…

wespeaker项目grpc-java客户端开发

非常重要的原始参考资料&#xff1a; 链接: triton-inference-server/client github/grpc java ps&#xff1a; 使用grpc协议的其它项目python/go可以参考git hub目录client/tree/main/src/grpc_generated下的其它项目 其它链接&#xff1a; 想要系统了解triton-inference-ser…

R语言:箱线图绘制(添加平均值趋势线)

箱线图绘制 1. 写在前面2.箱线图绘制2.1 相关R包导入2.2 数据导入及格式转换2.3 ggplot绘图 1. 写在前面 今天有时间把之前使用过的一些代码和大家分享&#xff0c;其中箱线图绘制我认为是非常有用的一个部分。之前我是比较喜欢使用origin进行绘图&#xff0c;但是绘制的图不太…

鸿蒙内核框架

1 内核概述 内核简介 用户最常见到并与之交互的操作系统界面&#xff0c;其实只是操作系统最外面的一层。操作系统最重要的任务&#xff0c;包括管理硬件设备&#xff0c;分配系统资源等&#xff0c;我们称之为操作系统内在最重要的核心功能。而实现这些核心功能的操作系统模…

VS编译器对scanf函数不安全报错的解决办法(详细步骤)

&#x1f4da;博客主页&#xff1a;爱敲代码的小杨. ✨专栏&#xff1a;《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更新的动力❤️ &#x1f64f;小杨水平有…

kubesphere部署k8s-v1.23.10

功能&#xff1a; &#x1f578; 部署 Kubernetes 集群 &#x1f517; Kubernetes 多集群管理 &#x1f916; Kubernetes DevOps &#x1f50e; 云原生可观测性 &#x1f9e9; 基于 Istio 的微服务治理 &#x1f4bb; 应用商店 &#x1f4a1; Kubernetes 边缘节点管理 &#x1…