MATLAB में xkcd शैली के रेखांकन


224

xkcd- शैली का ग्राफ

तो प्रतिभाशाली लोगों पता लगा है कि कैसे बनाने के लिए xkcd शैली रेखांकन मेथेमेटिका में , LaTeX में , पायथन में और अनुसंधान में पहले से ही।

ऊपर दिए गए प्लॉट की तरह लगने वाले प्लाट को बनाने के लिए MATLAB का उपयोग कैसे किया जा सकता है?

मैंने क्या कोशिश की है

मैंने विगली लाइनें बनाईं, लेकिन मैं विगली एक्सिस नहीं पा सका। एकमात्र उपाय जो मैंने सोचा था कि उन्हें विगली लाइनों के साथ ओवरराइट करना था, लेकिन मैं वास्तविक कुल्हाड़ियों को बदलने में सक्षम होना चाहता हूं। मुझे काम करने के लिए हास्य फ़ॉन्ट भी नहीं मिल सका, जो कोड बिट का उपयोग किया गया था:

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

विगली लाइन के लिए, मैंने एक छोटे यादृच्छिक शोर को जोड़ने और चौरसाई के साथ प्रयोग किया:

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

लेकिन मैं सफेद पृष्ठभूमि उनके चारों ओर दिखाई नहीं दे सकता जब वे अंतरंग ...


9
एडिट को संतुष्ट करने के लिए लगता है "पहले कुछ बुनियादी शोध किया था"। साथ ही, यहां के जवाब अच्छे हैं। फिर से खोलने।
शोग

जवाबों:


117

मुझे इसे हल करने के दो तरीके दिखाई देते हैं: पहला तरीका प्लॉट सुविधाओं के x / y निर्देशांक में कुछ घबराना जोड़ना है। इसका लाभ यह है कि आप आसानी से एक प्लॉट को संशोधित कर सकते हैं, लेकिन यदि आप उन्हें एक्सकेडीफाइड ( @Rody Oldenhuis का समाधान देखें ) करना चाहते हैं, तो आपको स्वयं कुल्हाड़ियों को आकर्षित करना होगा । दूसरा तरीका एक गैर-चिड़चिड़ा भूखंड बनाना है, और imtransformछवि को यादृच्छिक विरूपण लागू करने के लिए उपयोग करना है। इसका यह लाभ है कि आप इसे किसी भी प्लॉट के साथ उपयोग कर सकते हैं, लेकिन आप एक संपादन योग्य प्लॉट नहीं बल्कि एक छवि के साथ समाप्त करेंगे।

मैं पहले # 2 दिखाऊंगा, और मेरा प्रयास नीचे # 1 पर (यदि आप # 1 बेहतर पसंद करते हैं, तो रोड़ी के समाधान को देखें )!

यहां छवि विवरण दर्ज करें

: यह समाधान दो प्रमुख कार्यों पर निर्भर करता है EXPORT_FIG फ़ाइल विनिमय से एक विरोधी aliased स्क्रीनशॉट, और प्राप्त करने के लिए 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)

यहाँ घबराने पर मेरा प्रारंभिक प्रयास है

यहां छवि विवरण दर्ज करें

%# 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
एसओ पर अपने समय का आनंद लें जब आप कर सकते हैं! ;)
gnovice

2
@gnovice: यह मेरा तीसरा एक होगा। मुझे आशा है कि मुझे यह अब तक पता चल गया है :)
जोनास

@ जोनास अच्छी नौकरी! मुझे लगता है कि आपके # 2 को अब तक सभी समाधानों के बीच, विगल्स के लिए सही महसूस हुआ। हालांकि, यह अभी भी बड़ी विगली टिक्स, पाठ के चारों ओर एक फ्रेम, और हाथ से घुमावदार रेखाओं को पाठ से एक रेखा तक इंगित करने में चूक जाता है ...
bla

2
EXPORT_FIG के लिए +1। विरोधी अलियासिंग के लिए मेरे सभी रेखांकन को और अधिक मनभावन धन्यवाद।
यमनको

1
@ जेसन: क्षमा करें, यह उस समय मेरे निकटतम उपलब्ध था।
जोनास

92

सभी विभिन्न प्लॉटिंग फ़ंक्शंस को फिर से लागू करने के बजाय, मैं एक जेनेरिक टूल बनाना चाहता था जो किसी भी मौजूदा प्लॉट को एक एक्सकॉन्डर प्लॉट प्लॉट में बदल सके।

इस दृष्टिकोण का मतलब है कि आप मानक MATLAB फ़ंक्शंस का उपयोग करके प्लॉट बना सकते हैं और उन्हें स्टाइल कर सकते हैं और फिर जब आप पूरा कर लेते हैं, तब आप प्लॉट की समग्र शैली को संरक्षित करते हुए प्लॉट को xkcd शैली में फिर से प्रस्तुत कर सकते हैं।

उदाहरण

भूखंड यहां छवि विवरण दर्ज करें

बार और प्लॉट

यहां छवि विवरण दर्ज करें

बॉक्स प्लॉट यहां छवि विवरण दर्ज करें

यह काम किस प्रकार करता है

समारोह एक कुल्हाड़ी के बच्चों पर पुनरावृत्ति करके काम करता है। यदि बच्चे टाइप के हैं lineया patchयह उन्हें थोड़ा परेशान करता है। यदि बच्चा प्रकार का hggroupहै, तो उप-बच्चों पर पुनरावृत्ति करता है hggroup। मेरे पास अन्य प्लॉट प्रकारों का समर्थन करने की योजना है, जैसे कि image, लेकिन यह स्पष्ट नहीं है कि xkcd शैली के लिए छवि को विकृत करने का सबसे अच्छा तरीका क्या है।

अंत में यह सुनिश्चित करने के लिए कि विकृतियां एक समान दिखती हैं (अर्थात, छोटी लाइनें लंबी लाइनों से अधिक विकृत नहीं होती हैं), मैं पिक्सेल में लाइन की लंबाई को मापता हूं और फिर इसकी लंबाई के लिए आनुपातिक नमूना लेता हूं। मैं फिर हर Nth नमूने में शोर जोड़ता हूं, जिसमें समान या कम मात्रा में विरूपण होता है।

कोड

कोड की कई सौ पंक्तियों को चिपकाने के बजाय मैं सिर्फ स्रोत के एक जिस्ट से लिंक करूंगा । इसके अतिरिक्त स्रोत कोड और उपरोक्त उदाहरण उत्पन्न करने के लिए कोड स्वतंत्र रूप से उपलब्ध GitHub है

जैसा कि आप उदाहरणों से देख सकते हैं, यह अभी तक स्वयं कुल्हाड़ियों को विकृत नहीं करता है हालांकि मैं इसे लागू करने की योजना बना रहा हूं जैसे ही मैंने ऐसा करने का सबसे अच्छा तरीका निकाला।


4
अच्छा! मैं एक समान कोड का काम कर रहा हूं जो export_figमार्ग को लागू करता है, अर्थात यह पहले प्लॉट xkcd-like को प्रारूपित करता है, और फिर चित्र को विकृत करता है।
जोनास

4
धन्यवाद। मुझे वास्तव में बॉक्स प्लॉट्स पर गर्व है। मैं हैकिंग के स्तर पर आश्चर्यचकित था कि उन भूखंडों को दिखाने के लिए आवश्यक था।
स्लैटन

मैं अपनी पूरी प्रस्तुति को एक्सकेसीडी शैली में बदलने के लिए इसका उपयोग करूंगा।
यमनकेयो

हाय स्लेटन, वे शानदार हैं! मेरे पास बस एक ही सवाल है, क्या कुल्हाड़ी के कार्टियोनी / xkcd-ish बनाने का भी कोई तरीका है? यह मेरे लिए यह करना होगा और मैं इसका उपयोग करने में सक्षम होगा! :-) बहुत धन्यवाद ...
स्पेसी

@Learnaholic AFAIK मैटलैब कुल्हाड़ी प्रदान करने के तरीके को बदलने के लिए कोई एपी (प्रलेखित या
अविवादित)

63

पहला चरण ... आप जैसा सिस्टम फॉन्ट पाते हैं ( listfontsजो उपलब्ध है उसे देखने के लिए फ़ंक्शन का उपयोग करें ) या xkcd से लिखावट शैली से मेल खाने वाले को स्थापित करें । मुझे इस ब्लॉग पोस्ट में उल्लिखित उपयोगकर्ता ch00f से एक " ह्यूमन सैन्स" ट्रू टाइप फ़ॉन्ट मिला , और इसे अपने बाद के उदाहरणों के लिए उपयोग करूंगा।

जैसा कि मैं इसे देखता हूं, आपको आमतौर पर इस प्रकार के रेखांकन बनाने के लिए तीन अलग-अलग संशोधित ग्राफिक्स ऑब्जेक्ट की आवश्यकता होगी: एक एक्सिस ऑब्जेक्ट , एक लाइन ऑब्जेक्ट और एक टेक्स्ट ऑब्जेक्ट । आप चीजों को आसान बनाने के लिए एक एनोटेशन ऑब्जेक्ट भी चाहते हैं, लेकिन मैं इस बात के लिए मजबूर हूं कि अभी के लिए उपरोक्त तीन वस्तुओं की तुलना में इसे लागू करना अधिक कठिन हो सकता है।

मैंने रैपर फ़ंक्शंस बनाए जो तीन ऑब्जेक्ट्स बनाए, कुछ संपत्ति सेटिंग्स को ओवरराइड करके उन्हें और अधिक एक्सकैंडी की तरह बनाया। एक सीमा यह है कि उनके द्वारा उत्पादित नए ग्राफिक्स कुछ मामलों में अपडेट नहीं किए जाएंगे (जैसे अक्षों का आकार बदलने पर टेक्स्ट ऑब्जेक्ट पर बाउंडिंग बॉक्स), लेकिन इसे अधिक पूर्ण ऑब्जेक्ट-ओरिएंटेड कार्यान्वयन के साथ जिम्मेदार माना जा सकता है जिसमें हैंडल से विरासत में मिला है। वर्ग , घटनाओं और श्रोताओं , आदि का उपयोग करते हुए , अब के लिए, यहाँ मेरे सरल कार्यान्वयन हैं:

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

और यहाँ एक नमूना स्क्रिप्ट है जो उपरोक्त कॉमिक को फिर से बनाने के लिए इनका उपयोग करता है। मैंने ginputमाउस के साथ प्लॉट में पॉइंट पॉइंट्स का उपयोग करके लाइनों को फिर से बनाया , उन्हें कैप्चर किया, फिर उन्हें प्लॉट किया कि मुझे कैसा चाहिए:

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

और (ट्रम्पेट्स) यहाँ परिणामी साजिश है! "

यहां छवि विवरण दर्ज करें


2
आश्चर्यजनक! मेरी एकमात्र टिप्पणी यह ​​है कि पाठ से इंगित होने वाली रेखाएं पतली और अधिक घुमावदार (कम विगली) होनी चाहिए।
bla

4
यह शानदार है, हालांकि साजिश अलियासिंग से ग्रस्त है। मैंने उस से निपटने के तरीके के बारे में एक संक्षिप्त पोस्ट लिखी है: hugocarr.com/index/xkcd-style-graphs-in-matlab
Huguenot

28

ठीक है, यहाँ मेरा कम-क्रूड-लेकिन-अभी भी नहीं-काफी-अभी तक प्रयास है:

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

परिणाम:

मतलाब में XKCD नकल

करने के लिए काम:

  1. बेहतर कार्य खोजें (बेहतर उन्हें टुकड़ा-वार परिभाषित करें)
  2. "एनोटेशन" जोड़ें और उनके द्वारा वर्णित वक्रों को लहराती लाइनें
  3. कॉमिक सैंस से बेहतर फ़ॉन्ट खोजें!
  4. एक फंक्शन में सब कुछ सामान्य करें plot2xkcdताकि हम किसी भी प्लॉट / फिगर को xkcd स्टाइल में बदल सकें ।

1
रंग और कुल्हाड़ियों के साथ अच्छा काम! मुझे लगता है कि वे थोड़ा बहुत चिड़चिड़े हैं, हालांकि। वैसे भी +1।
जोनास

@HighPerormanceMark: मुझे अभी भी नहीं लगता कि यह सब बहुत उपयोगी है, हालांकि, यह बहुत मजेदार है :)
Rody Oldenhuis

@RodyOldenhuis क्यों उपयोगी नहीं है? मुझे मूल भूखंडों की तुलना में स्टाइल वाले भूखंड बेहतर दिख रहे हैं। शैली जोड़ना निश्चित रूप से एक वैध कार्य है।
स्लैटन ऑक्ट

2
@ सेलेटन: आइए एक बहुत ही उन्नत संख्या में क्रंचिंग टूल लें, जो सुपर-कुशल होने के लिए डिज़ाइन किया गया था, जो यथासंभव सुंदर, प्रकाशित-तैयार प्लॉट बनाने में सक्षम है, और चलो इसे बनाने के लिए उपयोग करें ... ** कॉमिक्स ** इसके साथ । क्षमा करें, यह सिर्फ मूर्खतापूर्ण है। हालांकि यह बहुत मजेदार है , यही वजह है कि यहां ज्यादातर लोग उखड़ गए और सवाल फिर से खुल गया। क्या यह भविष्य के आगंतुकों के लिए किसी काम का होगा? खैर ... यह है प्रेरित करते हैं। शायद यह कुछ लोगों को मतलाब सीखने के लिए आमंत्रित करेगा। लेकिन xkcd- शैली के काम को ठीक से करने के लिए हैक और तकनीकों की आवश्यकता होगी जो कि
उह

6
@RodyOldenhuis: मैं, एक के लिए, अपनी प्रस्तुतियों में इन रेखांकन का उपयोग करूंगा। और यह आमतौर पर "हैक्स" के साथ होता है जो आप वास्तव में सीखते हैं कि पर्यावरण कैसे काम करता है।
जोनास
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.