只熟悉 Matlab,Matlab的交互性属实强悍,编辑模式下实时修改属性查看成图效果,还可导出代码方便复用;
下面给出一些典型案例:
先睹为快
二维曲线算是最最常见的一种曲线了,它能反应两个变量的因果关系;
clear;clc;close all; x = linspace(1, 200, 100); y1 = log(x) + 1; y2 = log(x) + 2; figure; plot(x, y1); hold on plot(x, y2, 'LineWidth', 2); hold off legend('y1', 'y2');
调整线的粗细,给人感觉就不一样;
或者说这个颜色可能你觉得不好看,查阅帮助文档里给的的标准颜色也都不喜欢;
没关系,我整理了 28 种个人觉得比较好看的颜色,自行做一下颜色搭配,一般够用了;
figure; plot(x, y1, 'LineWidth', 2, 'Color', [0.21, 0.21, 0.67]); hold on plot(x, y2, 'LineWidth', 2, 'Color', [0.99, 0.49, 0.00]); hold off legend('y1', 'y2');
常用来比较理论数据和实验数据的趋势关系;
figure; y3 = y1 + rand(1, 100) - 0.5; plot(x, y1, 'LineWidth', 2, 'Color', [0.21, 0.21, 0.67]); hold on % 设置数据点的形状、数据点的填充颜色、数据点的轮廓颜色 plot(x, y3, 'o', 'LineWidth', 2, 'Color', [0.46, 0.63, 0.90], 'MarkerFaceColor', [0.35, 0.90, 0.89], 'MarkerEdgeColor', [0.18, 0.62, 0.17]); hold off
用不同的颜色、数据点大小表征不同数值,更加直观;
更详细的案例分析:
% 先自己做一个 colormap c_map = [0.00, 0.36, 0.67 0.68, 0.42, 0.89 0.44, 0.62, 0.98 0.10, 0.67, 0.59 0.99, 0.57, 0.59 0.28, 0.55, 0.86 0.96, 0.62, 0.24 0.30, 0.90, 0.56 0.12, 0.46, 0.71 0.46, 0.63, 0.90 0.96, 0.37, 0.40 0.14, 0.76, 0.71 0.99, 0.50, 0.02 0.00, 0.57, 0.76 0.35, 0.90, 0.89 0.17, 0.62, 0.47 0.21, 0.21, 0.67 0.99, 0.49, 0.00 0.98, 0.74, 0.44 0.97, 0.60, 0.58 0.18, 0.62, 0.17 0.68, 0.87, 0.53 0.12, 0.46, 0.70 0.65, 0.79, 0.89 0.95, 0.99, 0.69 0.74, 0.92, 0.68 0.37, 0.81, 0.72 0.01, 0.72, 0.77]; scatter(x, y3, x, x, 'filled'); colormap(c_map);
figure; fill([x, NaN], [y2, NaN], [x, NaN], 'EdgeColor', 'interp', 'LineWidth', 2);
正常条形图没啥好说的,这里演示绘制带有误差线的柱状图:
figure; m = 5; n = 3; x = 1:m; y = rand(m, n) + 2; % 误差限 neg = rand(m, n); pos = rand(m, n); % 绘制柱状图 h = bar(x, y); % 设置三个系列颜色 h(1, 1).FaceColor = [0.00, 0.36, 0.67]; h(1, 2).FaceColor = [0.68, 0.42, 0.89]; h(1, 3).FaceColor = [0.44, 0.62, 0.98]; % 单独设置第二个系列第二个柱子颜色 h(1, 2).FaceColor = 'flat'; h(1, 2).CData(2,:) = [0.21, 0.21, 0.67]; % 获取误差线 x 值 xx = zeros(m, n); for i = 1 : n xx(:, i) = h(1, i).XEndPoints'; end % 绘制误差线 hold on errorbar(xx, y, neg, pos, 'LineStyle', 'none', 'Color', 'm', 'LineWidth', 1.5); hold off % 绘制图例 legend({'A1', 'A2', 'A3'}); % 设置 x 轴标签 set(gca, 'XTickLabel', {'label1', 'label2', 'label3', 'label4', 'label5'});
x = 0.4:0.1:2*pi; y1 = sin(2*x); y2 = sin(x); % 确定 y1 和 y2 的上下边界 maxY = max([y1; y2]); minY = min([y1; y2]); % 确定填充多边形,按照顺时针方向来确定点 % fliplr 实现左右翻转 xFill = [x, fliplr(x)]; yFill = [maxY, fliplr(minY)]; figure fill(xFill, yFill, [0.21, 0.21, 0.67]); hold on % 绘制轮廓线 plot(x, y1, 'k', 'LineWidth', 2) plot(x, y2, 'k', 'LineWidth', 2) hold off
% 函数交叉区域填充 figure; % 这是三个方程 g1 = @(x,y) 1 - x.^2.*y/20; g2 = @(x, y) 1 - (x+y-5).^2/30 - (x-y-12).^2/120; g3 = @(x, y) 1 - 80./(x.^2 + 8*y + 5); % 把他们的图像画出来 h1 = fimplicit(g1, [0, 10], 'LineWidth', 2); hold on h2 = fimplicit(g2, [0, 10], 'LineWidth', 2); h3 = fimplicit(g3, [0, 10], 'LineWidth', 2); legend('g1', 'g2', 'g3'); % 问题来了,这个 y 值怎么确定 x1 = h1.XData; y1 = h1.YData; x2 = h2.XData; y2 = h2.YData; x3 = h3.XData; y3 = h3.YData; % 发现 x1, x2 是从大到小的,逆序搞一下 x1 = fliplr(x1); x2 = fliplr(x2); y1 = fliplr(y1); y2 = fliplr(y2); % 接下来,确定相交区域,主要看这三个关键点:g1-g2, g1-g3, g2-g3 % 数据长度不一样,难搞了,借助【数据提示】功能吧 pt1 = [3.11069, 2.06667]; pt2 = [8.53623, 0.266667]; pt3 = [7.7847, 1.8]; % 确定三个范围 idx1 = find(x1 >= pt1(1) & x1 < pt2(1)); idx2 = find(x2 >= pt1(1) & x2 < pt3(1)); idx3 = find(x3 >= pt3(1) & x3 < pt2(1)); x1 = x1(idx1); x2 = x2(idx2); x3 = x3(idx3); y1 = y1(idx1); y2 = y2(idx2); y3 = y3(idx3); % 一定要是一个闭环 xFill = [x1, fliplr(x3), fliplr(x2)]; yFill = [y1, fliplr(y3), fliplr(y2)]; fill(xFill, yFill, [0.21, 0.21, 0.67]); hold off
figure; load('accidents.mat','hwydata') ind = 1:51; drivers = hwydata(:,5); yyaxis left scatter(ind, drivers, 'LineWidth', 2); title('Highway Data'); xlabel('States'); ylabel('Licensed Drivers (thousands)'); pop = hwydata(:,7); yyaxis right scatter(ind, pop, 'LineWidth', 2); ylabel('Vehicle Miles Traveled (millions)');
figure; x = linspace(0,10); y1 = 2*sin(3*x); y2 = sin(3*x).*exp(0.5*x); %% 三个纵坐标演示,更多纵坐标可以按照此方法类推 y3 = 10*cos(3*x); % 控制 aies 的大小和位置,注意是相对于figure的,范围为[0, 1] % 三条线绘制到一起,注意数据都标准化到 y1 范围 maxY1 = max(y1); maxY2 = max(y2); maxY3 = max(y3); minY1 = min(y1); minY2 = min(y2); minY3 = min(y3); newY2 = (y2 - minY2)/(maxY2 - minY2); % 归一化 newY2 = newY2*(maxY1 - minY1) + minY1; % 反归一化 newY3 = (y3 - minY3)/(maxY3 - minY3); newY3 = newY3*(maxY1 - minY1) + minY1; % 画线 axes('position', [0.1 0.1 0.5 0.5]); plot(x, y1, 'k', x, newY2, 'r', x, newY3, 'ob--') ylabel('line1'); % 绘制另外两个空的坐标轴 h2 = axes('position', [0.65 0.1 0.005 0.5]); % 重复绘制,曲线颜色用白色,和figure背景色一致,看不出来即可 plot(x, y2, 'w') % 颜色,位置,曲线标签 set(h2, 'ycolor', 'r', 'yaxislocation', 'right', 'xtick', []) % 不知道为啥2018B版本边界显示不清楚,所以画一条线 hold on limX2 = get(h2, 'Xlim'); limY2 = get(h2, 'Ylim'); plot([limX2(2), limX2(2)], limY2, 'r'); hold off % 取消边框 box off ylabel('line2'); % h3 = axes('position', [0.75 0.1 0.005 0.5]); plot(x, y3, 'w') set(h3, 'ycolor', 'b', 'yaxislocation', 'right', 'xtick', []) hold on limX3 = get(h3, 'Xlim'); limY3 = get(h3, 'Ylim'); plot([limX3(2), limX3(2)], limY3, 'b'); hold off box off ylabel('line3'); % 取消坐标轴的颜色,和figure统一 % set(h1, 'color','none') % set(h2, 'color','none') % set(h3, 'color','none') % figure背景设置成白色 set(gcf,'color','white');
% 直接把 streamline 函数的帮助文档 demo 拷贝过来 [x, y] = meshgrid(0:0.1:1, 0:0.1:1); u = x; v = -y; startx = 0.1:0.1:0.9; starty = ones(size(startx)); % 需要获取所有流线的属性 figure; quiver(x, y, u, v); streamline(x, y, u, v, startx, starty);
% 直接把 streamline 函数的帮助文档 demo 拷贝过来 figure; [x, y] = meshgrid(0:0.1:1, 0:0.1:1); u = x; v = -y; startx = 0.1:0.1:0.9; starty = ones(size(startx)); % 需要获取所有流线的属性 lines = streamline(x, y, u, v, startx, starty); % 下面开始画箭头,涉及到坐标的转换 % 获取 Axes 位置 posAxes = get(gca, 'Position'); posX = posAxes(1); posY = posAxes(2); width = posAxes(3); height = posAxes(4); % 获取 Axes 范围 limX = get(gca, 'Xlim'); limY = get(gca, 'Ylim'); minX = limX(1); maxX = limX(2); minY = limY(1); maxY = limY(2); % 遍历,逐条流线加箭头 for i = 1 : length(lines) % 获取每条流线的数据 xData = lines(i).XData; yData = lines(i).YData; % 这里取的是最后两个点,一定要是相邻的两个点用来确定箭头方向 x0 = xData(end-1 : end); y0 = yData(end-1 : end); % 转换坐标到相对于figure的坐标 xNew = posX + (x0 - minX) / (maxX - minX) * width; yNew = posY + (y0 - minY) / (maxY - minY) * height; % 画箭头 hold on annotation('arrow', xNew, yNew, 'color', 'b'); end hold off title('带箭头的流线图');
figure; t = 0:pi/20:10*pi; xt = sin(t); yt = cos(t); plot3(xt, yt, t, '-o', 'Color', 'b', 'MarkerSize', 10, 'MarkerFaceColor', '#D9FFFF');
figure; x = -20:10:20; y = 0:100; % 随便生成的 5 组数据,也就是目标图上的 5 条曲线数据 z = zeros(5, 101); z(1, 1:10:end) = linspace(1, 10, 11); z(2, 1:10:end) = linspace(1, 20, 11); z(3, 1:10:end) = linspace(1, 5, 11); z(4, 5:10:end) = linspace(1, 10, 10); z(5, 80:2:end) = linspace(1, 5, 11); for i = 1:5 % x 方向每条曲线都是一个值,重复 y 的长度这么多次 xx = x(i)*ones(1, 101); % z 方向的值,每次取一条 zz = z(i, :); % plot3 在 xyz 空间绘制曲线,保证 x y z 长度一致即可 plot3(xx, y, zz, 'LineWidth', 2); hold on end hold off legend('line1', 'line2', 'line3', 'line4', 'line5');
% 如果把渐变曲线和三维曲线结合起来 figure; x = linspace(0, 2*pi, 50); y = sin(x); fill3([ones(size(x)), NaN], [x, NaN], [y, NaN], [x NaN], 'EdgeColor', 'interp', 'LineWidth', 2) hold on for i = 2 : 5 if mod(i, 2) == 0 y = sin(2*x); fill3([i * ones(size(x)), NaN], [x, NaN], [y, NaN], [x NaN], 'EdgeColor', 'interp', 'LineWidth', 2) else y = sin(10*x); fill3([i * ones(size(x)), NaN], [x, NaN], [y, NaN], [x NaN], 'EdgeColor', 'interp', 'LineWidth', 2) end end hold off
figure; [X,Y,Z] = sphere(16); x = [0.5*X(:); 0.75*X(:); X(:)]; y = [0.5*Y(:); 0.75*Y(:); Y(:)]; z = [0.5*Z(:); 0.75*Z(:); Z(:)]; S = repmat([70, 50, 20],numel(X), 1); C = repmat([1, 2, 3], numel(X), 1); s = S(:); c = C(:); h = scatter3(x, y, z, s, c); h.MarkerFaceColor = [0 0.5 0.5];
x = linspace(1, 200, 100); y1 = log(x) + 1; y2 = log(x) + 2; y3 = y1 + rand(1, 100) - 0.5; figure; scatter3(x, y2, y3, x, x, 'filled'); colormap(c_map);
[x, y, z] = peaks(30); figure; plot1 = subplot(1,2,1); surf(x, y, z); % 获取第一幅图的 colormap,默认为 parula cMap = colormap; plot2 = subplot(1,2,2); surf(x, y, z); % 下面设置的是第二幅图的颜色,默认是整个 figure 的 colormap(hot); % 设置第一幅图颜色显示为 parula set(plot1, 'Colormap', cMap);
% 一个坐标轴 figure; h1 = surf(x, y, z); freezeColors; hold on h2 = surf(x, y, z + 5); hold off colormap(hot);
figure; n = 300; [x, y, z] = peaks(n); subplot(2, 2, [1,3]) surf(x, y, z); shading interp view(0, 90) for i = 1:n for j = 1:n if x(i, j)^2 + 2 * y(i, j)^2 > 6 && 2 * x(i, j)^2 + y(i, j)^2 < 6 z(i, j) = NaN; end end end subplot(2, 2, 2) surf(x, y, z); shading interp view(0, 90) subplot(2, 2, 4) surf(x, y, z); shading interp
figure; [X, Y, Z] = peaks; subplot(2, 2, 1); contour(X, Y, Z, 20, 'LineWidth', 2); subplot(2, 2, 2); contour(X, Y, Z, '--', 'LineWidth', 2) subplot(2, 2, 3); v = [1, 1]; contour(X, Y, Z, v, 'LineWidth', 2); x = -2:0.2:2; y = -2:0.2:3; [X, Y] = meshgrid(x, y); Z = X.*exp(-X.^2-Y.^2); subplot(2, 2, 4); contour(X, Y, Z, 'ShowText','on', 'LineWidth', 2);
figure('Position', [0, 0, 900, 400]); subplot(1, 3, 1); [X, Y, Z] = sphere(50); contour3(X, Y, Z, 'LineWidth', 2); [X, Y] = meshgrid(-2:0.25:2); Z = X.*exp(-X.^2-Y.^2); subplot(1, 3, 2); contour3(X, Y, Z, [-0.2 -0.1 0.1 0.2], 'ShowText', 'on', 'LineWidth', 2) [X, Y, Z] = peaks; subplot(1, 3, 3); contour3(X, Y, Z, [2 2], 'LineWidth', 2);
figure; subplot(2, 2, 1); [X, Y, Z] = peaks(50); contourf(X, Y, Z); subplot(2, 2, 2); contourf(X, Y, Z,'--'); % 限定范围 subplot(2, 2, 3); contourf(X, Y, Z, [2 3], 'ShowText', 'on'); subplot(2, 2, 4); contourf(X, Y, Z,[2 2]);
figure; [X, Y, Z] = peaks(30); % 矢量场,曲面法线 [U, V, W] = surfnorm(X, Y, Z); % 箭头长度、颜色 quiver3(X, Y, Z, U, V, W, 0.5, 'r'); hold on surf(X,Y,Z); xlim([-3, 3]); ylim([-3, 3.2]); shading interp hold off view(0, 90);
clear;clc;close all; x = linspace(-3, 3, 30); y = linspace(-4, 4, 40); [X, Y] = meshgrid(x, y); Z = peaks(X, Y); Z(5:10, 15:20) = 0; z1 = max(Z); z2 = max(Z, [], 2); figure; subplot(3, 3, [1, 2]); plot(x, z1, 'LineWidth', 2); subplot(3, 3, [6, 9]); plot(z2, y, 'LineWidth', 2); subplot(3, 3, [4, 5, 7, 8]); surf(x, y, Z); xlim([-3, 3]); ylim([-4, 4]); view(0, 90); shading interp
figure; % 3*3 布局 tiledlayout(3, 3, 'TileSpacing', 'Compact'); % 占据 1*2,也就是 1 2 nexttile([1, 2]); plot(x, z1, 'LineWidth', 2); % 从第 6 个开始,占据 2*1,也就是 6 和 9 nexttile(6, [2, 1]); plot(z2, y, 'LineWidth', 2); % 从第 4 个开始,占据 2*2,也就是 4 5 7 8 nexttile(4, [2, 2]); surf(x, y, Z); xlim([-3, 3]); ylim([-4, 4]); view(0, 90); shading interp
clear;clc; x = linspace(-10, 10, 100); y = gauss(100, 5) ; figure; % 设置边缘颜色和宽度 bar(x, y, 'EdgeColor', 'none', 'BarWidth', 1);
clear;clc; z = rand(50); z(z >= 0.0 & z < 0.6) = 0.5; z(z >= 0.6 & z < 0.8) = 0.7; z(z >= 0.8 & z <= 1) = 0.9; for i = 1:30 z(randi(50, 1, 1) : end, i) = nan; end for i = 31:50 z(30 + randi(20, 1, 1) : end, i) = nan; end z(20:25, 40:45) = nan; figure; % ax = surf(z); ax = pcolor(z); view(0, 90); ax.EdgeColor = [1 1 1]; axis off
figure; for i = 1:50 for j = 1:50 if ~isnan(z(i, j)) x = [i - 1, i, i, i - 1]; y = [j - 1, j - 1, j, j]; c1 = 'w'; c2 = 'w'; if z(i, j) >= 0.1 c1 = 'black'; c2 = [0.65, 0.78, 0.56]; if z(i, j) >= 0.6 c2 = [0.98, 0.46, 0.23]; if z(i, j) >= 0.8 c2 = [0.99, 0.02, 0.02]; end end end patch(x, y, c2, 'EdgeColor', c1); end end end axis off
clear;clc; % 球面的坐标信息,为了看起来平滑一点,给到 100 [x, y, z] = sphere(100); % C 大小 C = 10; % H 大小 H = 5; figure; % 大球 surf(C*x, C*y, C*z, 'FaceColor', 'red', 'EdgeColor', 'none') hold on % 四个小球,都偏离一点位置,准确的位置需要计算,这里演示一个大概位置 surf(H*x, H*y, H*z + 10, 'FaceColor', 'blue', 'EdgeColor', 'none'); surf(H*x + 10, H*y, H*z - 3, 'FaceColor', 'blue', 'EdgeColor', 'none'); surf(H*x - 4, H*y - 10, H*z - 3, 'FaceColor', 'blue', 'EdgeColor', 'none'); surf(H*x - 4, H*y + 10, H*z - 3, 'FaceColor', 'blue', 'EdgeColor', 'none'); % 坐标轴设置 axis equal off % 光源,看起来更有立体感 light lighting gouraud
clear;clc; n = 1000; m = 1000; f = @(z) z^8 - 1; df = @(z) 8*z^7; [X, Y] = meshgrid(linspace(-2, 2, n), linspace(-2, 2, m)); A = nan(n, m); for i = 1:n for j = 1:m z0 = X(i, j) + 1i*Y(i, j); % Newton-Raphson z = z0; ite = 0; fz = f(z); while abs(fz) > 1e-6 && ite < 20 z = z - f(z)/df(z); fz = f(z); ite = ite + 1; end A(i, j) = ite; end end figure; pcolor(X, Y, A); % hold on % plot([1, -1, 0, 0], [0, 0, 1, -1], '.k', 'MarkerSize', 20); % hold off shading flat axis tight manual
% xlim([-0.5, 0]); % ylim([0.5, 1]); % 保存成视频 % set(gca, 'nextplot', 'replacechildren'); % v = VideoWriter('NRfractal.avi'); % open(v); % for k = 1:20 % pcolor(X, Y, A); % shading flat % xlim([-2*(1-k/25), 2*(1-k/25)]); % ylim([-2*(1-k/25), 2*(1-k/25)]); % frame = getframe(gcf); % writeVideo(v, frame); % end % (-0.19, 0.6557) % (-0.1, 0.651) % zx = zx*zx - zy*zy + cx % zy = 2*zx*zy+cy c = - 0.1 + 1i*0.651; radius = 32; [X, Y] = meshgrid(linspace(-1.5, 1.5, n), linspace(-1.5, 1.5, m)); A = nan(n, m); for i = 1:n for j = 1:m z = X(i, j) + 1i*Y(i, j); % Julia for ite = 1:1000 z = (z*z + c) ; if abs(z) > radius break; end end A(i, j) = ite; end end figure; pcolor(X, Y, A); shading flat axis tight manual
clear;clc; figure; % 读取地图文件 image = imread('World.jpg'); % 生成一个球面数据 [x, y, z] = sphere(200); % 绘制球体 p = surf(x, y, z); % 去网格线 shading interp; p.CData = image; % 纹理贴图 p.FaceColor = "texturemap"; axis equal; axis off % 光源,看起来更有立体感 % light % lighting gouraud % 光源颜色 handle = light('Color', [1 1 1]); t = 0; while t < 100 t = t + 1; view([t 10]); lightangle(handle, t, 0); pause(0.01); end
clear;clc; N = 500; z = peaks(N); % 选择 ROI 以外的不显示 for i = 1:N for j = 1:N if sqrt((i - N/2)*(i - N/2) + (j - N/2)*(j - N/2)) > 240 z(i, j) = nan; end end end % 自定义颜色 大概就是给特定范围值指定颜色 N = 14 * 5; crange = linspace(-6, 8, N); cmap = zeros(N, 3); for i = 1:N if crange(i) <= 0 cmap(i, :) = [0, 1, 0]; elseif crange(i) <= 3 cmap(i, :) = [0, 0, 1]; elseif crange(i) <= 6 cmap(i, :) = [1, 1, 0]; else cmap(i, :) = [1, 0, 0]; end end figure; surf(z) colormap(cmap); % 去网格 shading interp % 视角 view(0, 90); % 去坐标轴 axis off
clear; clc; x = 0:0.01:1; n = 1:9; len = length(n); im = cell(1, len); % 单独显示每个图 figure; for idx = 1:len subplot(3, 3, idx) plot(x, x.^idx, 'LineWidth',3) title(['y = x^', num2str(idx)]) end % 获取绘制对象 fig = figure(1); for idx = 1:len y = x.^idx; plot(x, y, 'LineWidth', 3) title(['y = x^', num2str(n(idx))]) % drawnow % pause(0.1); frame = getframe(fig); im{idx} = frame2im(frame); end % 输出文件名 % filename = 'testAnimated.gif'; % for idx = 1:len % % 制作gif文件,图像必须是index索引图像 % [A, map] = rgb2ind(im{idx}, 256); % if idx == 1 % imwrite(A, map, filename, 'gif', 'LoopCount', Inf, 'DelayTime', 0.3); % else % imwrite(A, map, filename, 'gif', 'WriteMode', 'append', 'DelayTime', 0.3); % end % end
% 二元方程 x^2*cos(y) + x*sinh(y^2) = 0 xy = linspace(-2, 2, 4); f = @(x, y) x.^2.*cos(y) + x.*sinh(y.^2); figure fimplicit(f, [-2, 2]);
figure; theta = 0:0.01:2*pi; rho = sin(2*theta).*cos(2*theta); tiledlayout(1, 2); nexttile; polarplot(theta, rho, 'c', 'LineWidth', 2); nexttile; rMax = 2*max(rho); % 这个看不到线,因为只有一个重复的点 polarplot([0, 2*pi], [rMax, rMax]); hold on polarplot(theta, rho, 'm', 'LineWidth', 2); hold off
clear;clc;close all; % 限定范围 width = 10; height = 10; % 最多产生的圆的个数 circleNumber = 100; % 记录每个圆的横坐标、纵坐标、半径 paras = zeros(circleNumber, 3); num = 0; hold on while num < circleNumber num = num + 1; % 圆半径小于1或者设定为固定值 r = rand; % 在范围内随机坐标 xPos = rand*(width-2*r) + r; yPos = rand*(height-2*r) + r; % 记录坐标、半径 paras(num,:) = [xPos, yPos, r]; % 判断每个圆的位置是否不相切、不相交 if num > 1 % 新产生的圆和之前产生的所有圆计算距离 xs = paras(1:num - 1, 1); ys = paras(1:num - 1, 2); rs = paras(1:num - 1, 3); dist1 = sqrt((xPos - xs).^2 + (yPos - ys).^2); dist2 = abs(r + rs); % 如果相离则绘制当前产生的圆,否则就重新生成一个圆 if all(dist1 > dist2) rectangle('Position', [xPos-r, yPos-r, 2*r, 2*r], 'Curvature', [1 1]); axis equal else r = rand; xPos = rand*(width-2*r) + r; yPos = rand*(height-2*r) + r; paras(num,:) = [xPos,yPos,r]; % 防止死循环 temp = 0; maxTry = 100; while any(dist1 <= dist2) && temp < maxTry temp = temp + 1; dist1 = sqrt((xPos - xs).^2 + (yPos - ys).^2); dist2 = abs(r + rs); end if all(dist1 > dist2) rectangle('Position', [xPos-r, yPos-r, 2*r, 2*r], 'Curvature', [1 1]); axis equal end end end end axis([0 width 0 height]) box on hold off
figure; x1 = ones(1, 5); x2 = 2 * ones(1, 11); x3 = 3 * ones(1, 8); y1 = 4:8; y2 = 1:11; y3 = 2.5:9.5; for i = 1:5 for j = 1:11 plot([x1(i), x2(j)], [y1(i), y2(j)], 'k'); hold on end end for i = 1:11 for j = 1:8 plot([x2(i), x3(j)], [y2(i), y3(j)], 'k'); end end scatter(x1, y1, 200, 'k', 'MarkerFaceColor', 'r'); scatter(x2, y2, 200, 'k', 'MarkerFaceColor', 'y'); scatter(x3, y3, 200, 'k', 'MarkerFaceColor', 'k'); plot([1.5, 1.5], [0, 11], 'k--'); plot([2.5, 2.5], [0, 11], 'k--'); hold off axis off text(1.5, 11.75, '输入层'); text(2, 11.75, '隐藏层'); text(2.5, 11.75, '输出层');
clear;clc; x0 = 0; y0 = 0; r1 = 2; r2 = 1; theta = 0:pi/50:2*pi; for i = 1:length(theta) % 系列小圆的圆心坐标 极坐标方式 x = x0 + r1 * cos(theta(i)); y = y0 + r1 * sin(theta(i)); % 以小圆圆心画圆 极坐标方式 xx = x + r2 * cos(theta); yy = y + r2 * sin(theta); plot(xx, yy, 'k'); hold on end hold off % 限定显示范围 xlim([-3, 3]); ylim([-3, 3]); % x y 轴等宽 axis equal % 紧凑 axis tight
figure; % 生成数据点 [x, y] = meshgrid(30:39); x = x(:); y = y(:); scatter(x, y, 100, 'red'); hold on % 随机填充几个点 number = 5; index_x = randi(9, 1, number) + 30; index_y = randi(9, 1, number) + 30; scatter(index_x, index_y, 100, 'blue', 'MarkerFaceColor', 'blue'); hold off % 显示网格 grid on % 网格属性 set(gca, 'GridAlpha', 1, 'GridColor', [0 0 0], 'GridLineStyle', '--');
从大学到现在,我使用Java已经将近20年,日常也带实习生,还在公司内部做training,所以可以分享下我的经验,希望对你有用。
因为是在工作中培训,就必然有两个约束:实用、时间紧,因此就不能像大学那样,把所有的知识点都面面俱到的讲到。而只能挑基础的,实用的,难理解的讲。至于其他边边角角的知识,就一笔带过。一则没有时间,二则不常用,再则既使讲了,学生印象也不深刻。总之一句话:“好钢用在刀刃上”。
下面,就根据我的实践,具体谈下学习过程:
1.基础知识
我学习java的时候,先是通读了《Java编程思想》,然后是《Java核心技术》。当时这两本书还不像现在这么厚,而刚才我把案头的《Java核心技术》第9版翻了翻,上下两册已经1700多页了,可想而知,如果要把它通读一遍,且不说把所有的代码都调通,就是当小说读,估计也需要些时间。
但我现在教学依然首推《Java核心技术》,主要是体系完整,实例多,可操作性强。但对初学者,我一般是只讲前6章,也就是下面的内容:
就《Java核心技术》第9版来说,也就是到250页为止,加把劲,1个月拿下完全没问题。
因为你是自学,所以建议你一定要把其中的代码都调通,课后的作业尽量去做。除此之外,还有两点特别重要:
#.学习笔记
因为你是自学,不像在企业中学了就能够实践,印象自然特别深刻。而自学因为没有实践的及时反馈,所以记笔记就显得特别重要。因为记笔记就像写作一样,是整理思路的绝佳方法。同时学习笔记也是你以后开发,面试的绝好资料。
学习编程,人跟人是不一样的,别人觉得难理解的东西,对你却不一定;而你觉得难理解的东西,别人可能又会觉得特简单。而学习笔记就是自己专有的“难点手册”,有点像高考时的“错题本”,以后无论是在面试前,还是在日常工作中,随时都可以翻出来看看,自是获益匪浅。
#.分门别类保存demo
学习笔记是很好的文字资料,但编程界有句话说的特别好,所谓“no code, no text”,意思就是说:千言万语都没有一段代码来的实在。
以我的经验,在你在学习的过程中,就某个知识点,无论当时理解的多透彻,调试的多棒,只要时间一长,等到了实用的时候,肯定会碰到各种各样的问题,一些看似简单的东西,此时死活就是调不通,正所谓人到事中迷。这个时候,如果你手头恰有运行良好的demo,打开参考一下(甚至直接拷贝过来),问题自然迎刃而解。而且因为这些demo都是你亲手调试出来,印象自然特别深刻,一碰到问题,在脑子中自会立刻涌现。
所以说,在学习的过程,一定要善待你调通的demo,千万不要用完了就扔,等后来碰到困难,想要用时却找不到,追愧莫及。正确的做法就是把所有调通的demo,分门别类的保存起来,到时候查起来自是得心应手。
人都说“书到用时方恨少”,其实代码也是这样,所谓“demo用时方恨少”。
2.Spring
目前在Java EE开发中,Spring已经成为和Java核心库一样的基础设施,所以说如果想成为一个合格的Java程序员,Spring肯定绕不开。另一方面,如果掌握了Spring体系,Java基本上就算入门了,就有能力进行一些实用级的开发了。
但Spring本身也是日渐复杂,衍生项目越来越多,但最最核心的概念依旧是IOC和AOP,掌握了这两个概念,再把Spring MVC学会,再学习其他的衍生项目就会平滑很多。
同时,因为Spring本身就应用了许多优雅的设计理念,所以学习Spring的过程,也是加强Java基础知识学习的过程。因此等你掌握了Spring,原来很多你理解不透彻的Java特性,此时就会恍然大悟,包括接口、抽象类等。
我学习Spring,读的第一本书是《Spring实战》,坦率的说,书很一般,但市面上比它好的书,我却没有遇到过。还有一本《Spring源码深度解析》也不错,对Spring的设计理念讲的尤其透彻,虽然整本书读起来有些艰涩,但前几章却生动有趣,也是整本书的精华。所以建议你在学习Spring之前,先把该书的前几章通读一下,然后再回过头来学习《Spring实战》会顺利很多。
以我经验,要学透Spring,终极的方法还是阅读源码(我当时就是这么干的),待把Spring的核心源码通读了,人就真的自由了(所谓无真相不自由),不仅是对Spring,而是对整个Java体系。以后再遇到其他框架,大概一眼就能看出其中的脉络,所谓到了“看山不是山”的境界。但这都是后话,可以作为以后你努力的方向。
和学习Java基础知识一样,学习Spring也一定要记笔记,一定要分门别类保存demo。
老实说,Spring对初学者不算简单,因此最好能有个好老师带一下,不用太长时间,2个课时即可,然后就是在你遇到大的困难时,能及时的点拨下。
以我的经验,要初步掌握Spring,大概需要1到1个半月的时间。
3.其他知识
Spring是Java编程的基础设施,但真要进入到实际项目的开发,还有些东西绕不过,包括 MySql,Mybatis,Redis,Servlet等,但如果你经过Spring的洗礼,这些东西相对就简单多了,以我的经验,1个月的时间足够了。
4.实践
学习Java,光学不练肯定是不行的。但因为是自学,所以就没有实际的产品让你练手,但也没有关系,谁大学还没有做过毕业设计呢?以我的经验,大家最爱的“学生管理系统”依旧是个很好的练手系统。
别看“学生管理系统”逻辑简单,但麻雀虽小五脏俱全,其中数据库设计、Mybatis,Spring、SpringMVC,Servlet、Tomcat一个都不缺,绝对的练手好伴侣。
还有,虽然你的学习重点在Java,因为要做一个完整的demo,前端的配合肯定少不了。因此就免少不了要学一些简单的JS、HTML知识,但因为前端本就是个很大的topic,所以一定要控制好边界,千万不要顾此失彼。就“学生管理系统”来说,在前端上,只要实现一个包含table、textbox、button,能发送REST请求到server,能实现学生的“增删改查”的简单页面即可。
作为一个练手项目,目标就是把Java的主要技能点串起来,所以自不求尽善尽美(也不可能),所以1个月时间足够了。
.最后
按照上面的过程,4个月的时间刚刚好。当然Java的体系是很庞大的,还有很多更高级的技能需要掌握,但不要着急,这些完全可以放到以后工作中边用别学。
学习编程就是一个由混沌到有序的过程,所以你在学习过程中,如果一时碰到理解不了的知识点,大可不必沮丧,更不要气馁,这都是正常的不能再正常的事情了,不过是“人同此心,心同此理”的暂时而已。
在日常的教学中,我常把下面这句话送给学员们,今天也把它送给你:
“道路是曲折的,前途是光明的!”
祝你好运!
--- 上面是原答案 ---
我把上面的内容作了下整理,画了学习路线图,内容也有些升级,供参考。
因为有朋友,通过留言或私信方式问我:Java中有哪些知识已经过时,不需要再学习了?
回答的多了,就感觉这是一个普遍的问题,因此统一整理了下,作为这篇文章的补充,希望对你有用。