MATLAB'da xkcd tarzı grafikler


225

xkcd tarzı grafik

Yani yetenekli insanlar nasıl çözdüklerini xkcd tarzı grafikler Mathematica , LaTeX'te , Python ve Ar zaten.

Yukarıdaki gibi görünen bir arsa üretmek için MATLAB'ı nasıl kullanabilirim?

Ne denedim

Kıvrımlı çizgiler oluşturdum ama kıvrımlı eksenler alamadım. Düşündüğüm tek çözüm, onları wiggly çizgilerle yazmaktı, ancak gerçek eksenleri değiştirmek istiyorum. Ayrıca mizah yazı tipi çalışmak için alamadım, kullanılan kod biti:

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

Kıvrımlı çizgi için, küçük bir rastgele gürültü ekleyerek ve yumuşatmayı denedim:

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

Ama kesiştiklerinde beyaz arka planın etraflarında göründüğünü yapamadım ...


9
Edit, "önce bazı temel araştırmalar yaptı" gibi görünüyor. Ayrıca, buradaki cevaplar güzel. Yeniden açılış.
Shog9

Yanıtlar:


118

Bunu çözmenin iki yolunu görüyorum: İlk yol, çizim özelliklerinin x / y koordinatlarına biraz titreşim eklemektir. Bunun avantajı, bir çizimi kolayca değiştirebilmenizdir, ancak eksenleri xkcdyfied yapmak istiyorsanız kendiniz çizmeniz gerekir ( @Rody Oldenhuis çözümüne bakın ). İkinci yol, titrek olmayan bir grafik oluşturmak imtransformve görüntüye rastgele bir bozulma uygulamak için kullanmaktır . Bu, herhangi bir arsa ile kullanabileceğiniz avantajına sahiptir, ancak düzenlenebilir bir arsa değil, bir görüntü elde edersiniz.

Önce # 2'yi göstereceğim ve aşağıda # 1'deki girişimim (# 1'i daha iyi isterseniz, Rody's çözümüne bakın !).

resim açıklamasını buraya girin

Bu çözüm iki temel işleve dayanmaktadır: Kenar yumuşatılmış bir ekran görüntüsü almak için dosya değişiminden EXPORT_FIG ve bir dönüşüm elde etmek için IMTRANSFORM .

%# 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)

İşte benim ilk titreme girişimim

resim açıklamasını buraya girin

%# 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')

4
Mümkün olduğunca SO üzerinde zaman tadını çıkarın ! ;)
gnovice

2
@gnovice: Üçüncü benim olacak. İnşallah şimdiye kadar anladım :)
Jonas

@Jonas iyi iş çıkardın! Sanırım # 2, şimdiye kadarki tüm çözümler arasında kıpır kıpır kıpır kıpır kıpır kıpır kıpır kıpır kıpır kıpır kıpır. Ancak, yine de büyük kıvrımlı keneleri, metnin etrafındaki bir çerçeveyi özlüyor ve metinden bir çizgiye işaret etmek için elle çizilmiş eğri çizgiler ...
bla

2
EXPORT_FIG için +1. Kenar yumuşatma sayesinde tüm grafiklerimi daha hoş hale getirmek.
Yamaneko

1
@JasonS: Üzgünüm, o zaman sahip olduğum en yakın şeydi.
Jonas

92

Tüm çeşitli çizim işlevlerini yeniden uygulamak yerine, mevcut herhangi bir çizimi bir xkcd tarzı grafiğe dönüştürebilecek genel bir araç oluşturmak istedim.

Bu yaklaşım, standart MATLAB işlevlerini kullanarak grafikler oluşturabileceğiniz ve stil uygulayabileceğiniz anlamına gelir ve daha sonra işiniz bittiğinde, grafiğin genel stilini korurken grafiği xkcd stilinde yeniden oluşturabilirsiniz.

Örnekler

Arsa Resim açıklamasını buraya girin

Bar ve Arsa

Resim açıklamasını buraya girin

Kutu ve Arsa Resim açıklamasını buraya girin

Nasıl çalışır

İşlev, bir eksendeki çocuklar üzerinde yineleme yaparak çalışır. Çocuklar tipteyse lineveya patchbiraz bozarsa. Çocuk türü ise, hggroupo zaman alt hggroup. Gibi diğer arsa türlerini destekleme planları var image, ama bir xkcd tarzı olması için görüntü deforme etmenin en iyi yolu nedir açık değil.

Son olarak, çarpıklıkların düzgün görünmesini sağlamak için (yani, kısa çizgiler uzun çizgilerden daha fazla bozulmaz), çizgi uzunluğunu piksel cinsinden ölçer ve ardından numuneyi uzunluğuyla orantılı olarak ölçerim. Daha sonra, az ya da çok aynı miktarda bozulmaya sahip çizgiler üreten her Nth örneğine gürültü eklerim.

Kod

Birkaç yüz satır kod yapıştırmak yerine, sadece kaynağın bir özüne bağlayacağım . Ek olarak, yukarıdaki örnekleri oluşturmak için kaynak kodu ve kod GitHub'da serbestçe kullanılabilir .

Örneklerden de görebileceğiniz gibi, bunu yapmanın en iyi yolunu bulur bulmaz uygulamaya koymayı planlasam da, eksenleri henüz çarpıtmıyor.


4
Güzel! export_figRotayı uygulayan benzer bir kod parçası çalışıyorum , yani ilk arsa xkcd benzeri biçimlendirir ve sonra resmi deforme eder.
Jonas

4
Teşekkürler. Kutu grafikleriyle gerçekten gurur duyuyorum. O parsellerin ortaya çıkmasını sağlamak için gereken hack düzeyine şaşırdım.
slayton

Sunumumun tamamını XKCD stiline dönüştürmek için kullanacağım.
Yamaneko

Merhaba Slayton, bunlar harika! Sadece bir sorum var, eksenleri çizgi film / xkcd-ish yapmanın bir yolu var mı? Bu benim için yapardı ve onu kullanabilecektim! :-) Çok teşekkürler ...
Spacey

@Learnaholic AFAIK matlab, eksenlerin oluşturulma şeklini değiştirmek için herhangi bir api (belgelenmiş veya belgesiz)
sağlamaz

63

İlk adım ... beğendiğiniz bir sistem yazı tipini bulun ( listfontsuygun olanı görmek için işlevi kullanın) veya xkcd'den el yazısı stiliyle eşleşen bir yazı tipi yükleyin . Bu blog gönderisinde bahsedilen ch00f kullanıcısından bir "Mizah Sans" TrueType yazı tipi buldum ve sonraki örneklerim için kullanacağım.

Gördüğüm gibi, bu tür grafikleri yapmak için genellikle üç farklı değiştirilmiş grafik nesnesine ihtiyacınız olacak: bir eksen nesnesi , bir çizgi nesnesi ve bir metin nesnesi . Ayrıca, bir açıklama nesnesinin işleri kolaylaştırmasını da isteyebilirsiniz , ancak şimdilik, yukarıdaki üç nesneden daha zor uygulanabileceğinden bahsetmiştim.

Üç nesneyi oluşturan sarmalayıcı işlevler oluşturdum, onları daha fazla xkcd benzeri yapmak için belirli özellik ayarlarını geçersiz kıldım. Bir sınırlama ürettikleri yeni grafik (metin nesneleri eksenleri boyutlandırma üzerinde sınırlama kutuları gibi) bazı durumlarda güncellenen olmayacak, ama bu devralmasını içerir daha eksiksiz bir nesne yönelimli uygulamasıyla açıklanabileceğini öne sapın dersleri , olayları ve dinleyicileri kullanarak , vb. Şimdilik, benim daha basit uygulamalarım:

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

Ve yukarıdaki çizgi romanı yeniden oluşturmak için bunları kullanan örnek bir komut dosyası. Çizimleri ginputfare ile işaretlemek, onları yakalamak ve daha sonra nasıl istediğimi çizmek için kullanarak satırları yeniden oluşturdum :

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');

Ve (trompetler) ortaya çıkan arsa !:

resim açıklamasını buraya girin


2
Olağanüstü! benim tek yorumum metinden işaret eden satırların daha ince ve daha kavisli (daha az kıvrımlı) olması gerektiğidir.
bla

4
Her ne kadar arsa takma işlemden muzdarip olsa da bu harika. Burada bununla
Huguenot

28

Tamam o zaman, işte benim daha az kaba ama yine de tam olarak orada değil girişimi:

%# 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

Sonuç:

Matlab'da XKCD taklidi

Yapılacak şeyler:

  1. Daha iyi işlevler bulun (bunları daha iyi tanımlayın)
  2. Açıkladıkları eğrilere "ek açıklamalar" ve dalgalı çizgiler ekleyin
  3. Comic Sans'ten daha iyi bir yazı tipi bulun!
  4. Herhangi bir grafiği / grafiği xkcd stiline çevirebilmemiz için her şeyi bir işleve plot2xkcddönüştürün .

1
Renkler ve baltalarla güzel iş! Yine de biraz fazla gergin olduklarını hissediyorum. Yine de +1.
Jonas

@HighPerormanceMark: Hala bunun çok yararlı olduğunu düşünmüyorum, ancak çok eğlenceli :)
Rody Oldenhuis

@RodyOldenhuis neden yararlı değil? Biçimli arazileri orijinal çizimlere göre daha iyi buluyorum. Stil eklemek kesinlikle geçerli bir işlevdir.
slayton

2
@slayton: Süper verimli olacak şekilde tasarlanmış çok güzel bir sayı gıcırdama aracı kullanalım, mümkün olduğunca hassas, yayınlamaya hazır arsalar yapabilir ve bunu yapmak için kullanalım ... ** çizgi roman ** . Üzgünüm, bu sadece aptalca. Ancak bu çok eğlencelidir , bu yüzden buradaki çoğu insan iptal edildi ve sorunun ne olduğu yeniden açıldı. Bu, gelecekteki ziyaretçilerin yararına olacak mı? Eh ... gelmez ilham veriyor. Belki de bazı insanları Matlab'ı öğrenmeye davet edecektir. Ancak xkcd tarzı düzgün çalışması için en azından şüpheli hack ve teknikler gerekir ...
Rody Oldenhuis

6
@RodyOldenhuis: Birincisi, bu grafikleri sunumlarımda kullanacağım. Ve genellikle ortamın nasıl çalıştığını gerçekten öğrenirsiniz "hackler" ile.
Jonas
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.