grafik gaya xkcd di MATLAB

225

grafik gaya xkcd

Jadi orang-orang berbakat telah menemukan cara membuat grafik gaya xkcd di Mathematica , di LaTeX , di Python dan di R sudah.

Bagaimana cara menggunakan MATLAB untuk menghasilkan plot yang terlihat seperti di atas?

Apa yang saya coba

Saya membuat garis wiggly, tetapi saya tidak bisa mendapatkan sumbu wiggly. Satu-satunya solusi yang saya pikirkan adalah menimpa mereka dengan garis-garis yang bergelombang, tetapi saya ingin dapat mengubah sumbu yang sebenarnya. Saya juga tidak dapat mengaktifkan font Humor, kode yang digunakan adalah:

 annotation('textbox',[left+left/8 top+0.65*top 0.05525 0.065],...
'String',{'EMBARRASSMENT'},...
'FontSize',24,...
'FontName','Humor',...
'FitBoxToText','off',...
'LineStyle','none');

Untuk garis wiggly, saya bereksperimen dengan menambahkan suara acak kecil dan menghaluskan:

 smooth(0.05*randn(size(x)),10)

Tapi aku tidak bisa membuat latar belakang putih muncul di sekitar mereka ketika mereka berpotongan ...

bla
sumber
9
Sunting tampaknya memuaskan "melakukan riset dasar terlebih dahulu". Juga, jawabannya di sini bagus. Pembukaan kembali.
Shog9

Jawaban:

118

Saya melihat dua cara untuk mengatasi ini: Cara pertama adalah menambahkan beberapa jitter ke koordinat x / y dari fitur plot. Ini memiliki keuntungan bahwa Anda dapat dengan mudah memodifikasi plot, tetapi Anda harus menggambar sendiri jika Anda ingin memilikinya xkcdyfied (lihat solusi @Rody Oldenhuis ' ). Cara kedua adalah membuat plot non-gugup, dan gunakan imtransformuntuk menerapkan distorsi acak pada gambar. Ini memiliki keuntungan bahwa Anda dapat menggunakannya dengan plot apa pun, tetapi Anda akan berakhir dengan gambar, bukan plot yang dapat diedit.

Saya akan menunjukkan # 2 pertama, dan upaya saya di # 1 di bawah (jika Anda suka # 1 lebih baik, lihat solusi Rody !).

masukkan deskripsi gambar di sini

Solusi ini bergantung pada dua fungsi utama: EXPORT_FIG dari pertukaran file untuk mendapatkan tangkapan layar anti-alias, dan IMTRANSFORM untuk mendapatkan transformasi.

%# define plot data
x = 1:0.1:10;
y1 = sin(x).*exp(-x/3) + 3;
y2 = 3*exp(-(x-7).^2/2) + 1;

%# plot
fh = figure('color','w');
hold on
plot(x,y1,'b','lineWidth',3);
plot(x,y2,'w','lineWidth',7);
plot(x,y2,'r','lineWidth',3);

xlim([0.95 10])
ylim([0 5])
set(gca,'fontName','Comic Sans MS','fontSize',18,'lineWidth',3,'box','off')

%# add an annotation 
 annotation(fh,'textarrow',[0.4 0.55],[0.8 0.65],...
     'string',sprintf('text%shere',char(10)),'headStyle','none','lineWidth',1.5,...
     'fontName','Comic Sans MS','fontSize',14,'verticalAlignment','middle','horizontalAlignment','left')

%# capture with export_fig
im = export_fig('-nocrop',fh);

%# add a bit of border to avoid black edges
im = padarray(im,[15 15 0],255);

%# make distortion grid
sfc = size(im);
[yy,xx]=ndgrid(1:7:sfc(1),1:7:sfc(2));
pts = [xx(:),yy(:)];
tf = cp2tform(pts+randn(size(pts)),pts,'lwm',12);
w = warning;
warning off images:inv_lwm:cannotEvaluateTransfAtSomeOutputLocations
imt = imtransform(im,tf);
warning(w)

%# remove padding
imt = imt(16:end-15,16:end-15,:);

figure('color','w')
imshow(imt)

Inilah upaya awal saya untuk jittering

masukkan deskripsi gambar di sini

%# define plot data
x = 1:0.1:10;
y1 = sin(x).*exp(-x/3) + 3;
y2 = 3*exp(-(x-7).^2/2) + 1;

%# jitter
x = x+randn(size(x))*0.01;
y1 = y1+randn(size(x))*0.01;
y2 = y2+randn(size(x))*0.01;

%# plot
figure('color','w')
hold on
plot(x,y1,'b','lineWidth',3);
plot(x,y2,'w','lineWidth',7);
plot(x,y2,'r','lineWidth',3);

xlim([0.95 10])
ylim([0 5])
set(gca,'fontName','Comic Sans MS','fontSize',18,'lineWidth',3,'box','off')
Jonas
sumber
4
Nikmati waktu Anda di SO selagi bisa! ;)
gnovice
2
@ layanan: Ini akan menjadi yang ketiga. Saya harap saya sudah tahu sekarang :)
Jonas
@Jonas kerja bagus! Saya pikir # 2 Anda merasa cocok untuk goyangan, di antara semua solusi sejauh ini. Namun, masih merindukan kutu besar yang menggeliat, bingkai di sekitar teks, dan garis-garis melengkung yang digambar tangan untuk menunjuk dari teks ke garis ...
bla
2
+1 untuk EXPORT_FIG. Mengubah semua grafik saya lebih menyenangkan berkat anti-aliasing.
Yamaneko
1
@JasonS: maaf, itu yang paling dekat yang saya miliki saat itu.
Jonas
92

Daripada menerapkan kembali semua fungsi plot yang beragam, saya ingin membuat alat generik yang dapat mengubah plot yang ada menjadi plot gaya xkcd.

Pendekatan ini berarti Anda dapat membuat plot dan menatanya menggunakan fungsi standar MATLAB dan kemudian setelah selesai Anda kemudian dapat membuat kembali plot dalam gaya xkcd sambil mempertahankan keseluruhan gaya plot.

Contohnya

Merencanakan Masukkan deskripsi gambar di sini

Bar & Plot

Masukkan deskripsi gambar di sini

Box & Plot Masukkan deskripsi gambar di sini

Bagaimana itu bekerja

Fungsi ini bekerja dengan mengulangi anak-anak dari kapak. Jika anak-anak dari tipe lineatau patchitu sedikit mendistorsi mereka. Jika anak adalah tipe hggroupmaka iterates pada sub-anak dari hggroup. Saya memiliki rencana untuk mendukung jenis plot lainnya, seperti image, tetapi tidak jelas apa cara terbaik untuk mendistorsi gambar untuk memiliki gaya xkcd.

Akhirnya untuk memastikan bahwa distorsi terlihat seragam (yaitu, garis pendek tidak terdistorsi lebih dari garis panjang), saya mengukur panjang garis dalam piksel dan kemudian mengambil sampel yang sebanding dengan panjangnya. Saya kemudian menambahkan noise ke setiap sampel N yang menghasilkan garis yang memiliki jumlah distorsi yang kurang lebih sama.

Kode

Daripada menempelkan beberapa ratus baris kode, saya hanya akan menautkan ke inti sumbernya . Selain itu kode sumber dan kode untuk menghasilkan contoh-contoh di atas tersedia secara bebas GitHub .

Seperti yang dapat Anda lihat dari contoh, itu belum mengubah sumbu sendiri meskipun saya berencana untuk menerapkan segera setelah saya mencari cara terbaik untuk melakukan itu.

Slayton
sumber
4
Bagus! Saya telah mengerjakan bagian kode yang serupa yang mengimplementasikan export_figrute, yaitu memformat plot seperti xkcd, dan kemudian mendistorsi gambar.
Jonas
4
Terima kasih. Saya sangat bangga dengan plot kotak. Saya terkejut pada tingkat peretasan yang diperlukan untuk membuat plot itu muncul.
slayton
Saya akan menggunakannya untuk mengubah seluruh presentasi saya menjadi gaya XKCD.
Yamaneko
Hai Slayton, itu luar biasa! Saya hanya punya satu pertanyaan, apakah ada cara untuk juga membuat sumbu kartun / xkcd-ish? Itu akan melakukannya untuk saya dan saya akan dapat menggunakannya! :-) Terima kasih banyak ...
Spacey
@Learnaholic AFAIK matlab tidak menyediakan api (didokumentasikan atau tidak berdokumen) apa pun untuk mengubah cara kapak diberikan
slayton
63

Langkah pertama ... temukan font sistem yang Anda sukai (gunakan fungsi listfontsuntuk melihat apa yang tersedia) atau instal font yang cocok dengan gaya tulisan tangan dari xkcd . Saya menemukan font TrueType "Humor Sans" dari pengguna ch00f yang disebutkan dalam posting blog ini , dan akan menggunakannya untuk contoh saya selanjutnya.

Seperti yang saya lihat, Anda biasanya membutuhkan tiga objek grafik yang dimodifikasi untuk membuat grafik seperti ini: objek sumbu , objek garis , dan objek teks . Anda mungkin juga menginginkan objek anotasi untuk mempermudah, tetapi saya perkirakan untuk saat ini karena mungkin lebih sulit untuk diterapkan daripada tiga objek di atas.

Saya membuat fungsi wrapper yang menciptakan tiga objek, mengesampingkan pengaturan properti tertentu untuk membuatnya lebih seperti xkcd. Satu batasan adalah bahwa grafik baru yang mereka hasilkan tidak akan diperbarui dalam kasus-kasus tertentu (seperti kotak pembatas pada objek teks ketika mengubah ukuran sumbu), tetapi itu dapat dipertanggungjawabkan dengan implementasi berorientasi objek yang lebih lengkap yang melibatkan mewarisi dari pegangan kelas , menggunakan acara dan pendengar , dll. Untuk saat ini, ini adalah implementasi sederhana saya:

xkcd_axes.m:

function hAxes = xkcd_axes(xkcdOptions, varargin)

  hAxes = axes(varargin{:}, 'NextPlot', 'add', 'Visible', 'off', ...
               'XLimMode', 'manual', 'YLimMode', 'manual');

  axesUnits = get(hAxes, 'Units');
  set(hAxes, 'Units', 'pixels');
  axesPos = get(hAxes, 'Position');
  set(hAxes, 'Units', axesUnits);
  xPoints = round(axesPos(3)/10);
  yPoints = round(axesPos(4)/10);
  limits = [xlim(hAxes) ylim(hAxes)];
  ranges = [abs(limits(2) - limits(1)) abs(limits(4) - limits(3))];
  backColor = get(get(hAxes, 'Parent'), 'Color');
  xColor = get(hAxes, 'XColor');
  yColor = get(hAxes, 'YColor');
  line('Parent', hAxes, 'Color', xColor, 'LineWidth', 3, ...
       'Clipping', 'off', ...
       'XData', linspace(limits(1), limits(2), xPoints), ...
       'YData', limits(3) + rand(1, xPoints).*0.005.*ranges(2));
  line('Parent', hAxes, 'Color', yColor, 'LineWidth', 3, ...
       'Clipping', 'off', ...
       'YData', linspace(limits(3), limits(4), yPoints), ...
       'XData', limits(1) + rand(1, yPoints).*0.005.*ranges(1));

  xTicks = get(hAxes, 'XTick');
  if ~isempty(xTicks)
    yOffset = limits(3) - 0.05.*ranges(2);
    tickIndex = true(size(xTicks));
    if ismember('left', xkcdOptions)
      tickIndex(1) = false;
      xkcd_arrow('left', [limits(1) + 0.02.*ranges(1) xTicks(1)], ...
                 yOffset, xColor);
    end
    if ismember('right', xkcdOptions)
      tickIndex(end) = false;
      xkcd_arrow('right', [xTicks(end) limits(2) - 0.02.*ranges(1)], ...
                 yOffset, xColor);
    end
    plot([1; 1]*xTicks(tickIndex), ...
         0.5.*[-yOffset; yOffset]*ones(1, sum(tickIndex)), ...
         'Parent', hAxes, 'Color', xColor, 'LineWidth', 3, ...
         'Clipping', 'off');
    xLabels = cellstr(get(hAxes, 'XTickLabel'));
    for iLabel = 1:numel(xLabels)
      xkcd_text(xTicks(iLabel), yOffset, xLabels{iLabel}, ...
                'HorizontalAlignment', 'center', ...
                'VerticalAlignment', 'middle', ...
                'BackgroundColor', backColor);
    end
  end

  yTicks = get(hAxes, 'YTick');
  if ~isempty(yTicks)
    xOffset = limits(1) - 0.05.*ranges(1);
    tickIndex = true(size(yTicks));
    if ismember('down', xkcdOptions)
      tickIndex(1) = false;
      xkcd_arrow('down', xOffset, ...
                 [limits(3) + 0.02.*ranges(2) yTicks(1)], yColor);
    end
    if ismember('up', xkcdOptions)
      tickIndex(end) = false;
      xkcd_arrow('up', xOffset, ...
                 [yTicks(end) limits(4) - 0.02.*ranges(2)], yColor);
    end
    plot(0.5.*[-xOffset; xOffset]*ones(1, sum(tickIndex)), ...
         [1; 1]*yTicks(tickIndex), ...
         'Parent', hAxes, 'Color', yColor, 'LineWidth', 3, ...
         'Clipping', 'off');
    yLabels = cellstr(get(hAxes, 'YTickLabel'));
    for iLabel = 1:numel(yLabels)
      xkcd_text(xOffset, yTicks(iLabel), yLabels{iLabel}, ...
                'HorizontalAlignment', 'right', ...
                'VerticalAlignment', 'middle', ...
                'BackgroundColor', backColor);
    end
  end

  function xkcd_arrow(arrowType, xArrow, yArrow, arrowColor)
    if ismember(arrowType, {'left', 'right'})
      xLine = linspace(xArrow(1), xArrow(2), 10);
      yLine = yArrow + rand(1, 10).*0.003.*ranges(2);
      arrowScale = 0.05.*ranges(1);
      if strcmp(arrowType, 'left')
        xArrow = xLine(1) + arrowScale.*[0 0.5 1 1 1 0.5];
        yArrow = yLine(1) + arrowScale.*[0 0.125 0.25 0 -0.25 -0.125];
      else
        xArrow = xLine(end) - arrowScale.*[0 0.5 1 1 1 0.5];
        yArrow = yLine(end) + arrowScale.*[0 -0.125 -0.25 0 0.25 0.125];
      end
    else
      xLine = xArrow + rand(1, 10).*0.003.*ranges(1);
      yLine = linspace(yArrow(1), yArrow(2), 10);
      arrowScale = 0.05.*ranges(2);
      if strcmp(arrowType, 'down')
        xArrow = xLine(1) + arrowScale.*[0 0.125 0.25 0 -0.25 -0.125];
        yArrow = yLine(1) + arrowScale.*[0 0.5 1 1 1 0.5];
      else
        xArrow = xLine(end) + arrowScale.*[0 -0.125 -0.25 0 0.25 0.125];
        yArrow = yLine(end) - arrowScale.*[0 0.5 1 1 1 0.5];
      end
    end
    line('Parent', hAxes, 'Color', arrowColor, 'LineWidth', 3, ...
         'Clipping', 'off', 'XData', xLine, 'YData', yLine);
    patch('Parent', hAxes, 'FaceColor', arrowColor, ...
          'EdgeColor', arrowColor, 'LineWidth', 2, 'Clipping', 'off', ...
          'XData', xArrow + [0 rand(1, 5).*0.002.*ranges(1)], ...
          'YData', yArrow + [0 rand(1, 5).*0.002.*ranges(2)]);
  end

end

xkcd_text.m:

function hText = xkcd_text(varargin)

  hText = text(varargin{:});
  set(hText, 'FontName', 'Humor Sans', 'FontSize', 13, ...
      'FontWeight', 'normal');

  backColor = get(hText, 'BackgroundColor');
  edgeColor = get(hText, 'EdgeColor');
  if ~strcmp(backColor, 'none') || ~strcmp(edgeColor, 'none')
    hParent = get(hText, 'Parent');
    extent = get(hText, 'Extent');
    nLines = size(get(hText, 'String'), 1);
    extent = extent + [-0.5 -0.5 1 1].*0.25.*extent(4)./nLines;
    yPoints = 5*nLines;
    xPoints = round(yPoints*extent(3)/extent(4));
    noiseScale = 0.05*extent(4)/nLines;
    set(hText, 'BackgroundColor', 'none', 'EdgeColor', 'none');
    xBox = [linspace(extent(1), extent(1) + extent(3), xPoints) ...
            extent(1) + extent(3) + noiseScale.*rand(1, yPoints) ...
            linspace(extent(1) + extent(3), extent(1), xPoints) ...
            extent(1) + noiseScale.*rand(1, yPoints)];
    yBox = [extent(2) + noiseScale.*rand(1, xPoints) ...
            linspace(extent(2), extent(2) + extent(4), yPoints) ...
            extent(2) + extent(4) + noiseScale.*rand(1, xPoints) ...
            linspace(extent(2) + extent(4), extent(2), yPoints)];
    patch('Parent', hParent, 'FaceColor', backColor, ...
          'EdgeColor', edgeColor, 'LineWidth', 2, 'Clipping', 'off', ...
          'XData', xBox, 'YData', yBox);
    hKids = get(hParent, 'Children');
    set(hParent, 'Children', [hText; hKids(hKids ~= hText)]);
  end

end

xkcd_line.m:

function hLine = xkcd_line(xData, yData, varargin)

  yData = yData + 0.01.*max(range(xData), range(yData)).*rand(size(yData));
  line(xData, yData, varargin{:}, 'Color', 'w', 'LineWidth', 8);
  hLine = line(xData, yData, varargin{:}, 'LineWidth', 3);

end

Dan inilah contoh skrip yang menggunakan ini untuk membuat ulang komik di atas. Saya membuat ulang garis dengan menggunakan ginputuntuk menandai titik dalam plot dengan mouse, menangkapnya, lalu memplotnya seperti yang saya inginkan:

xS = [0.0359 0.0709 0.1004 0.1225 0.1501 0.1759 0.2219 0.2477 0.2974 0.3269 0.3582 0.3895 0.4061 0.4337 0.4558 0.4797 0.5074 0.5276 0.5589 0.5810 0.6013 0.6179 0.6271 0.6344 0.6381 0.6418 0.6529 0.6713 0.6842 0.6934 0.7026 0.7118 0.7265 0.7376 0.7560 0.7726 0.7836 0.7965 0.8149 0.8370 0.8573 0.8867 0.9033 0.9346 0.9659 0.9843 0.9936];
yS = [0.2493 0.2520 0.2548 0.2548 0.2602 0.2629 0.2629 0.2657 0.2793 0.2657 0.2575 0.2575 0.2602 0.2629 0.2657 0.2766 0.2793 0.2875 0.3202 0.3856 0.4619 0.5490 0.6771 0.7670 0.7970 0.8270 0.8433 0.8433 0.8243 0.7180 0.6199 0.5272 0.4510 0.4128 0.3392 0.2711 0.2275 0.1757 0.1485 0.1131 0.1022 0.0858 0.0858 0.1022 0.1267 0.1567 0.1594];

xF = [0.0304 0.0488 0.0727 0.0967 0.1335 0.1630 0.2090 0.2348 0.2698 0.3011 0.3269 0.3545 0.3803 0.4153 0.4466 0.4724 0.4945 0.5110 0.5350 0.5516 0.5608 0.5700 0.5755 0.5810 0.5884 0.6013 0.6179 0.6363 0.6492 0.6584 0.6676 0.6731 0.6842 0.6860 0.6934 0.7007 0.7136 0.7265 0.7394 0.7560 0.7726 0.7818 0.8057 0.8444 0.8794 0.9107 0.9475 0.9751 0.9917];
yF = [0.0804 0.0940 0.0967 0.1049 0.1185 0.1458 0.1512 0.1540 0.1649 0.1812 0.1812 0.1703 0.1621 0.1594 0.1703 0.1975 0.2411 0.3065 0.3801 0.4782 0.5708 0.6526 0.7452 0.8106 0.8324 0.8488 0.8433 0.8270 0.7888 0.7343 0.6826 0.5981 0.5300 0.4782 0.3910 0.3420 0.2847 0.2248 0.1621 0.0995 0.0668 0.0395 0.0232 0.0177 0.0204 0.0232 0.0259 0.0204 0.0232];

xE = [0.0267 0.0488 0.0856 0.1409 0.1759 0.2164 0.2514 0.3011 0.3269 0.3637 0.3969 0.4245 0.4503 0.4890 0.5313 0.5608 0.5939 0.6344 0.6694 0.6934 0.7192 0.7394 0.7523 0.7689 0.7891 0.8131 0.8481 0.8757 0.9070 0.9346 0.9604 0.9807 0.9936];
yE = [0.0232 0.0232 0.0232 0.0259 0.0259 0.0259 0.0313 0.0259 0.0259 0.0259 0.0368 0.0395 0.0477 0.0586 0.0777 0.0886 0.1213 0.1730 0.2466 0.2902 0.3638 0.5082 0.6499 0.7916 0.8924 0.9414 0.9550 0.9387 0.9060 0.8760 0.8542 0.8379 0.8188];

hFigure = figure('Position', [300 300 700 450], 'Color', 'w');
hAxes = xkcd_axes({'left', 'right'}, 'XTick', [0.45 0.60 0.7 0.8], ...
                  'XTickLabel', {'YARD', 'STEPS', 'DOOR', 'INSIDE'}, ...
                  'YTick', []);

hSpeed = xkcd_line(xS, yS, 'Parent', hAxes, 'Color', [0.5 0.5 0.5]);
hFear = xkcd_line(xF, yF, 'Parent', hAxes, 'Color', [0 0.5 1]);
hEmb = xkcd_line(xE, yE, 'Parent', hAxes, 'Color', 'r');

hText = xkcd_text(0.27, 0.9, ...
                  {'WALKING BACK TO MY'; 'FRONT DOOR AT NIGHT:'}, ...
                  'Parent', hAxes, 'EdgeColor', 'k', ...
                  'HorizontalAlignment', 'center');

hSpeedNote = xkcd_text(0.36, 0.35, {'FORWARD'; 'SPEED'}, ...
                       'Parent', hAxes, 'Color', 'k', ...
                       'HorizontalAlignment', 'center');
hSpeedLine = xkcd_line([0.4116 0.4282 0.4355 0.4411], ...
                       [0.3392 0.3256 0.3038 0.2820], ...
                       'Parent', hAxes, 'Color', 'k');
hFearNote = xkcd_text(0.15, 0.45, {'FEAR'; 'THAT THERE''S'; ...
                                   'SOMETHING'; 'BEIND ME'}, ...
                      'Parent', hAxes, 'Color', 'k', ...
                      'HorizontalAlignment', 'center');
hFearLine = xkcd_line([0.1906 0.1998 0.2127 0.2127 0.2201 0.2256], ...
                      [0.3501 0.3093 0.2629 0.2221 0.1975 0.1676], ...
                      'Parent', hAxes, 'Color', 'k');
hEmbNote = xkcd_text(0.88, 0.45, {'EMBARRASSMENT'}, ...
                     'Parent', hAxes, 'Color', 'k', ...
                     'HorizontalAlignment', 'center');
hEmbLine = xkcd_line([0.8168 0.8094 0.7983 0.7781 0.7578], ...
                     [0.4864 0.5436 0.5872 0.6063 0.6226], ...
                     'Parent', hAxes, 'Color', 'k');

Dan (trompet) inilah plot yang dihasilkan !:

masukkan deskripsi gambar di sini

gnovice
sumber
2
Hebat! satu-satunya komentar saya adalah bahwa garis yang menunjuk dari teks harus lebih tipis dan lebih melengkung (kurang goyah).
bla
4
Ini fantastis, meskipun plotnya menderita aliasing. Saya menulis posting singkat tentang cara menghadapinya di sini: hugocarr.com/index/xkcd-style-graphs-in-matlab
Huguenot
28

Baiklah kalau begitu, inilah upayaku yang kurang mentah-tapi-masih-belum-belum-cukup-belum:

%# init
%# ------------------------

noise = @(x,A) A*randn(size(x));
ns    = @(x,A) A*ones(size(x));


h = figure(2); clf, hold on
pos = get(h, 'position');
set(h, 'position', [pos(1:2) 800 450]);


blackline = {
    'k', ...
    'linewidth', 2};
axisline = {
    'k', ...
    'linewidth', 3};

textprops = {
    'fontName','Comic Sans MS',...
    'fontSize', 14,...
    'lineWidth',3};


%# Plot data
%# ------------------------
x  = 1:0.1:10;

y0 = sin(x).*exp(-x/30) + 3;
y1 = sin(x).*exp(-x/3) + 3;
y2 = 3*exp(-(x-7).^6/.05) + 1;

y0 = y0 + noise(x, 0.01);
y1 = y1 + noise(x, 0.01);
y2 = y2 + noise(x, 0.01);

%# plot
plot(x,y0, 'color', [0.7 0.7 0.7], 'lineWidth',3);

plot(x,y1, 'w','lineWidth',7);
plot(x,y1, 'b','lineWidth',3);

plot(x,y2, 'w','lineWidth',7);
plot(x,y2, 'r','lineWidth',3);




%# text
%# ------------------------
ll(1) = text(1.3, 4.2,...
    {'Walking back to my'
    'front door at night:'});

ll(2) = text(5, 0.7, 'yard');
ll(3) = text(6.2, 0.7, 'steps');
ll(4) = text(7, 0.7, 'door');
ll(5) = text(8, 0.7, 'inside');

set(ll, textprops{:});


%# arrows & lines
%# ------------------------

%# box around "walking back..."
xx = 1.2:0.1:3.74;
yy = ns(xx, 4.6) + noise(xx, 0.007);
plot(xx, yy, blackline{:})

xx = 1.2:0.1:3.74;
yy = ns(xx, 3.8) + noise(xx, 0.007);
plot(xx, yy, blackline{:})

yy = 3.8:0.1:4.6;
xx = ns(yy, 1.2) + noise(yy, 0.007);
plot(xx, yy, blackline{:})

xx = ns(yy, 3.74) + noise(yy, 0.007);
plot(xx, yy, blackline{:})

%# left arrow
x_arr = 1.2:0.1:4.8;
y_arr = 0.65 * ones(size(x_arr)) + noise(x_arr, 0.005);
plot(x_arr, y_arr, blackline{:})
x_head = [1.1 1.6 1.62];
y_head = [0.65 0.72 0.57];
patch(x_head, y_head, 'k')

%# right arrow
x_arr = 8.7:0.1:9.8;
y_arr = 0.65 * ones(size(x_arr)) + noise(x_arr, 0.005);
plot(x_arr, y_arr, blackline{:})
x_head = [9.8 9.3 9.3];
y_head = [0.65 0.72 0.57];
patch(x_head, y_head, 'k')

%# left line on axis
y_line = 0.8:0.1:1.1;
x_line = ns(y_line, 6.5) + noise(y_line, 0.005);
plot(x_line, y_line, blackline{:})

%# right line on axis
y_line = 0.8:0.1:1.1;
x_line = ns(y_line, 7.2) + noise(y_line, 0.005);
plot(x_line, y_line, blackline{:})

%# axes
x_xax = x;
y_xax = 0.95 + noise(x_xax, 0.01);
y_yax = 0.95:0.1:5;
x_yax = x(1) + noise(y_yax, 0.01);
plot(x_xax, y_xax, axisline{:})
plot(x_yax, y_yax, axisline{:})


% finalize 
%# ------------------------

xlim([0.95 10])
ylim([0 5])
axis off

Hasil:

XKCD imitasi di Matlab

Hal yang harus dilakukan:

  1. Temukan fungsi yang lebih baik (lebih baik mendefinisikannya sepotong-bijaksana)
  2. Tambahkan "anotasi" dan garis bergelombang ke kurva yang mereka gambarkan
  3. Temukan font yang lebih baik daripada Comic Sans!
  4. Generalisasi semuanya menjadi fungsi plot2xkcdsehingga kita dapat mengonversi plot / gambar apa pun menjadi gaya xkcd.
Rody Oldenhuis
sumber
1
Pekerjaan bagus dengan warna dan kapak! Saya merasa bahwa mereka agak terlalu gelisah. Tetap memberi +1.
Jonas
@HighPerormanceMark: Saya masih tidak berpikir ini semua sangat berguna, namun, itu sangat menyenangkan :)
Rody Oldenhuis
@RodyOldenhuis mengapa tidak berguna? Saya menemukan plot yang ditata lebih tampan daripada plot aslinya. Menambahkan gaya tentu saja merupakan fungsi yang valid.
slayton
2
@slayton: Mari kita ambil satu alat pengolah angka yang sangat canggih yang dirancang agar sangat efisien, mampu membuat plot yang indah, siap-cetak setepat mungkin, dan mari kita gunakan untuk membuat ... ** komik ** bersamanya . Maaf, itu konyol. Namun itu sangat menyenangkan , itulah sebabnya sebagian besar orang di sini terangkat dan apa yang membuat pertanyaan dibuka kembali. Apakah ini akan bermanfaat bagi pengunjung masa depan? Nah ... itu tidak menginspirasi. Mungkin itu akan mengundang beberapa orang untuk belajar Matlab. Tetapi membuat xkcd-style berfungsi dengan baik akan membutuhkan peretasan dan teknik yang uhm ... dipertanyakan setidaknya :)
Rody Oldenhuis
6
@RodyOldenhuis: Saya, salah satunya, akan menggunakan grafik ini dalam presentasi saya. Dan biasanya dengan "retasan" itulah Anda benar-benar mempelajari cara kerja lingkungan.
Jonas