<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Bence Kotis</title>
    <description>The latest articles on Forem by Bence Kotis (@wickdchromosome).</description>
    <link>https://forem.com/wickdchromosome</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F420177%2F014c406d-0154-49be-bf49-8f7331b05b47.jpg</url>
      <title>Forem: Bence Kotis</title>
      <link>https://forem.com/wickdchromosome</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/wickdchromosome"/>
    <language>en</language>
    <item>
      <title>Is the pain worth the gain? Writing webapps in C (Benchmarks vs Flask and Nodejs)</title>
      <dc:creator>Bence Kotis</dc:creator>
      <pubDate>Thu, 29 Oct 2020 02:49:34 +0000</pubDate>
      <link>https://forem.com/wickdchromosome/is-the-pain-worth-the-gain-writing-webapps-in-c-benchmarks-vs-flask-and-nodejs-14l0</link>
      <guid>https://forem.com/wickdchromosome/is-the-pain-worth-the-gain-writing-webapps-in-c-benchmarks-vs-flask-and-nodejs-14l0</guid>
      <description>&lt;p&gt;I wanted to do a performance comparison between &lt;strong&gt;Facil&lt;/strong&gt;(a web framework for C) against some more conventional tools, such as &lt;strong&gt;Flask&lt;/strong&gt;(Gunicorn server) and &lt;strong&gt;Nodejs&lt;/strong&gt;. &lt;strong&gt;Let's dive in!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Frehpvoeobs6b2bleonic.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Frehpvoeobs6b2bleonic.gif" alt="download (7)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How the benchmarking was done:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A simple webapp was made using each framework. These webapps embed the client's IP address in a page template and then serve it to the client.&lt;/li&gt;
&lt;li&gt;The 3 webapps were &lt;strong&gt;tested&lt;/strong&gt; under &lt;strong&gt;light&lt;/strong&gt;, &lt;strong&gt;medium&lt;/strong&gt; and &lt;strong&gt;heavy&lt;/strong&gt; load for &lt;strong&gt;5 minutes&lt;/strong&gt; each, running on a 1GB single core virtual machine(on Digital Ocean)&lt;/li&gt;
&lt;li&gt;They were evaluated on response time, CPU and memory consumption.&lt;/li&gt;
&lt;li&gt;In all of the plots below, the &lt;strong&gt;average value by Facil&lt;/strong&gt; is shown as a &lt;strong&gt;dotted blue line&lt;/strong&gt; for easier comparison. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  TLDR;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;If you are developing a &lt;strong&gt;high load web application&lt;/strong&gt;(over 1000 requests per second), writing it using &lt;strong&gt;Facil&lt;/strong&gt; could definitely &lt;strong&gt;pay its dividends over time&lt;/strong&gt; when it comes to &lt;strong&gt;resource consumption&lt;/strong&gt;, &lt;strong&gt;response time&lt;/strong&gt;(latency) and the &lt;strong&gt;variance of these two&lt;/strong&gt; factors(they tend to stay more predictable, even under a sudden surge in load)&lt;/li&gt;
&lt;li&gt;For &lt;strong&gt;light load&lt;/strong&gt; applications, &lt;strong&gt;Facil&lt;/strong&gt; might be &lt;strong&gt;overkill&lt;/strong&gt;(did not provide significant benefits) unless you are developing for an embedded platform or you prefer to develop in C compared to other languages&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Heavy load (~1100 requests per second)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Frehpvoeobs6b2bleonic.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Frehpvoeobs6b2bleonic.gif" alt="download (7)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Response Time
&lt;/h4&gt;

&lt;p&gt;Facil has come out on top by far when it comes to latency under heavy load. Facil managed to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Have less of a latency spike&lt;/strong&gt; (it responded better to a sudden surge in load at the beginning of the test)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Have much less variance in response time&lt;/strong&gt; (more reliable results)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Have a lesser average response time&lt;/strong&gt; under heavy load&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Resource Consumption
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fydphnt7en3ywv0u50802.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fydphnt7en3ywv0u50802.gif" alt="download (15)"&gt;&lt;/a&gt; &lt;br&gt;
When it comes to resource consumption, Facil also managed to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Have &lt;strong&gt;lesser resource consumption&lt;/strong&gt; in both ram and CPU, especially compared to Flask&lt;/li&gt;
&lt;li&gt;Have a &lt;strong&gt;lesser variance in resource consumption&lt;/strong&gt; compared to other frameworks&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Medium load (~400 requests/sec)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fkoonf15x9it5jt2vgf12.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fkoonf15x9it5jt2vgf12.gif" alt="download (12)"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Response Time
&lt;/h4&gt;

&lt;p&gt;Under medium load, Facil was:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;still leading ahead of Flask&lt;/strong&gt; in terms of response time, but &lt;strong&gt;Nodejs is catching up&lt;/strong&gt;(Facil was arguably a tiny bit better though).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Facil still had a better response to sudden load&lt;/strong&gt; in the beginning of the test than Nodejs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F43ahzkqyw02cdv68f4b1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F43ahzkqyw02cdv68f4b1.gif" alt="download (13)"&gt;&lt;/a&gt;&lt;br&gt;
In terms of resource consumption, under medium load, Facil:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is &lt;strong&gt;still significantly leading&lt;/strong&gt; in terms of &lt;strong&gt;RAM&lt;/strong&gt; consumption ahead of both Flask and Nodejs&lt;/li&gt;
&lt;li&gt;Had &lt;strong&gt;less of a CPU spike&lt;/strong&gt; under sudden load&lt;/li&gt;
&lt;li&gt;Had &lt;strong&gt;less variance in CPU consumption&lt;/strong&gt; compared to the other two candidates&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Light load (~100 requests/sec)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2g132bpa9a0a8dqsf30v.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2g132bpa9a0a8dqsf30v.gif" alt="download (10)"&gt;&lt;/a&gt;&lt;br&gt;
Under light load, Facil:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Had &lt;strong&gt;seemingly no advantage in response time&lt;/strong&gt; over the other frameworks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffj6nfpvb80jzbed6j1vq.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffj6nfpvb80jzbed6j1vq.gif" alt="download (14)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Facil had some minimal advantage&lt;/strong&gt; in RAM consumption compared to other frameworks&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Final notes
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Obviously this was just a simple test&lt;/strong&gt;, but it has shown that &lt;strong&gt;if you are expecting large loads&lt;/strong&gt;, &lt;strong&gt;want to keep hosting as cheap as possible&lt;/strong&gt; by minimizing resource consumption, or  &lt;strong&gt;doing development for embedded platforms&lt;/strong&gt;, a non-conventional framework like Facil might be worth looking into. &lt;/p&gt;

&lt;p&gt;You can find the source code for the 3 webapps under:&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/wickdChromosome" rel="noopener noreferrer"&gt;
        wickdChromosome
      &lt;/a&gt; / &lt;a href="https://github.com/wickdChromosome/simple_webapp_comparison" rel="noopener noreferrer"&gt;
        simple_webapp_comparison
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Repo for article comparing benchmarks for writing webapps in C, Flask, Nodejs
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


</description>
      <category>python</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>c</category>
    </item>
    <item>
      <title>Spicy plots with matplotlib</title>
      <dc:creator>Bence Kotis</dc:creator>
      <pubDate>Fri, 17 Jul 2020 19:45:56 +0000</pubDate>
      <link>https://forem.com/wickdchromosome/spicy-plots-with-matplotlib-1b0i</link>
      <guid>https://forem.com/wickdchromosome/spicy-plots-with-matplotlib-1b0i</guid>
      <description>&lt;p&gt;&lt;strong&gt;The full code used in this article in the form of a Jupyter notebook can be found&lt;/strong&gt; &lt;a href="https://github.com/wickdChromosome/spicy_plots_with_matplotlib"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  1. Use Google Fonts!
&lt;/h1&gt;

&lt;p&gt;Google Fonts has thousands of fonts you can download to make your plots look a bit more refined.&lt;/p&gt;

&lt;h4&gt;
  
  
  The easiest way to install new fonts if you are on Linux is using font-manager.
&lt;/h4&gt;

&lt;p&gt;On Debian or Ubuntu, you can install font-manager by doing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install font-manager
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Find your favorite font on Google Fonts.
&lt;/h4&gt;

&lt;p&gt;My current favorite on there would have to be &lt;a href="https://fonts.google.com/specimen/Roboto+Condensed"&gt;Roboto Condensed&lt;/a&gt;. Download and unzip your fonts, then add them(all the .tff files) inside font-manager by clicking the + button on the top left corner:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qKfzszS---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/cky5plbtz9155c47iqqa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qKfzszS---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/cky5plbtz9155c47iqqa.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Now if you open up a Jupyter notebook, you should be able to list all the fonts available to Matplotlib by doing:
&lt;/h4&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;#clear the matplotlib font cache (this is important!!!)
&lt;/span&gt;&lt;span class="err"&gt;!&lt;/span&gt;&lt;span class="n"&gt;rm&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt; &lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;matplotlib&lt;/span&gt;

&lt;span class="c1"&gt;#originally from: http://jonathansoma.com/lede/data-studio/matplotlib/list-all-fonts-available-in-matplotlib-plus-samples/
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;matplotlib.font_manager&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;IPython.core.display&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;HTML&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;make_html&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fontname&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"&amp;lt;p&amp;gt;{font}: &amp;lt;span style='font-family:{font}; font-size: 24px;'&amp;gt;{font}&amp;lt;/p&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;font&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;fontname&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;make_html&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;font&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;font&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;matplotlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;font_manager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fontManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ttflist&lt;/span&gt;&lt;span class="p"&gt;]))])&lt;/span&gt;
&lt;span class="n"&gt;HTML&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;div style='column-count: 2;'&amp;gt;{}&amp;lt;/div&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;After that, your new fonts should be ready for use by using the &lt;strong&gt;fontname&lt;/strong&gt; attribute in most matplotlib objects, like &lt;strong&gt;plt.title&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mH_Lasb5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zwqfv82zmovpvshzxknd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mH_Lasb5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zwqfv82zmovpvshzxknd.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  2. Use gifs/images to add some personality to your plots
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ryeWNqfi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/kk56hnuc8do0ox8erdx6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ryeWNqfi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/kk56hnuc8do0ox8erdx6.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  This plot looks about as boring as it gets.
&lt;/h4&gt;

&lt;p&gt;Lets write some code to create an image/gif overlay for our plot:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_overlay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base_im&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;overlay_im&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;newsize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;outname&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'output.gif'&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="s"&gt;'''Adds a png or gif to your plot'''&lt;/span&gt;

    &lt;span class="c1"&gt;#open both images
&lt;/span&gt;    &lt;span class="n"&gt;original_image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base_im&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;animated_gif&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;overlay_im&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;frames&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="c1"&gt;#used to store output frames for gif
&lt;/span&gt;
    &lt;span class="c1"&gt;#iterate over input gif
&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;ImageSequence&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Iterator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;animated_gif&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

        &lt;span class="c1"&gt;#resize each frame
&lt;/span&gt;        &lt;span class="n"&gt;frame&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;resize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newsize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
        &lt;span class="c1"&gt;#copy plot and paste gif frame on top
&lt;/span&gt;        &lt;span class="n"&gt;original_image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;original_image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;original_image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;paste&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;frames&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;original_image&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;#you can change the duration variable to change gif speed
&lt;/span&gt;    &lt;span class="n"&gt;frames&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;outname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;save_all&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;append_images&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;frames&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:],&lt;/span&gt; &lt;span class="n"&gt;duration&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After adding some images, the plot is a lot more eye-catching!&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EKPa14Om--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/nlxxsmr766b18jizcapb.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EKPa14Om--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/nlxxsmr766b18jizcapb.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The same code can be used to add animated gifs to your plot.&lt;/p&gt;

&lt;h4&gt;
  
  
  Gifs are a great way to annotate your plots and convey how you feel about your results:
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IzGpK-Fi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hd6tg3qscsthsxequxf1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IzGpK-Fi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hd6tg3qscsthsxequxf1.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--23pj1A5z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ksaj9bycadysmio0tawu.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--23pj1A5z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ksaj9bycadysmio0tawu.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I hope these tips gave you a bit of inspiration to spice up your plotting workflow. For the full code used in this article, refer to this &lt;a href="https://github.com/wickdChromosome/spicy_plots_with_matplotlib"&gt;Jupyter notebook&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>python</category>
      <category>datascience</category>
      <category>jupyter</category>
    </item>
    <item>
      <title>3 easy ways to speed up your python code within minutes</title>
      <dc:creator>Bence Kotis</dc:creator>
      <pubDate>Wed, 01 Jul 2020 22:29:21 +0000</pubDate>
      <link>https://forem.com/wickdchromosome/3-easy-ways-to-speed-up-your-python-code-in-minutes-h44</link>
      <guid>https://forem.com/wickdchromosome/3-easy-ways-to-speed-up-your-python-code-in-minutes-h44</guid>
      <description>&lt;h2&gt;
  
  
  I. Benchmark, benchmark, benchmark
&lt;/h2&gt;

&lt;p&gt;Benchmarking sounds like a tedious process, but if you already have working code separated into functions, it can be as easy as adding a decorator to the function you are trying to profile.&lt;/p&gt;

&lt;p&gt;First off, lets install &lt;strong&gt;line_profiler&lt;/strong&gt; so that we can measure the time spent on each line of code in our function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip3 install line_profiler
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This provides a decorator(&lt;strong&gt;profile&lt;/strong&gt;) that you can use to benchmark any function in your code line by line. As an example, lets say that we have the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#filename: test.py

@profile
def sum_of_lists(ls):
    '''Calculates the sum of an input list of lists'''

    s = 0
    for l in ls:
        for val in l:
            s += val

    return s


#create a list of lists
smallrange = list(range(10000))
inlist = [smallrange, smallrange, smallrange, smallrange]

#now sum them
list_sum = sum_of_lists(inlist)

print(list_sum)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will profile the &lt;strong&gt;sum_of_lists&lt;/strong&gt; function when called - notice the &lt;strong&gt;profile&lt;/strong&gt; decorator above the function definition.&lt;/p&gt;

&lt;p&gt;Now we can profile our code by doing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python3 -m line_profiler test.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which gives us:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5aqdv34vdcfwmjm2ps64.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5aqdv34vdcfwmjm2ps64.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The 5th column shows the percentage of the runtime spent on each line - this will point you to the section of your code that needs optimization the most, as this is where most of the runtime is spent. &lt;/p&gt;

&lt;p&gt;Keep in mind that this benchmarking library has significant overhead, but it's perfect for finding weak points in your code and replacing them with something more efficient. &lt;/p&gt;

&lt;p&gt;For running &lt;strong&gt;line_profiler&lt;/strong&gt; inside &lt;strong&gt;Jupyter&lt;/strong&gt; notebooks, check out the &lt;strong&gt;%%lprun&lt;/strong&gt; magic command.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Compile your Python modules using Cython
&lt;/h2&gt;

&lt;p&gt;If you don't want to modify your project at all but still want some performance gains for free, Cython is your friend.&lt;/p&gt;

&lt;p&gt;Although Cython is not a general purpose python to C compiler, Cython lets you compile your python modules into shared object files(.so), which can be loaded by your main python script. &lt;/p&gt;

&lt;p&gt;For this, you will need to have Cython, as well as a C compiler installed on your machine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip3 install cython
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are on a Debian, you can download GCC by doing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install gcc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lets separate the starting example code into 2 files, named test_cython.py and test_module.pyx:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#filename: test_module.pyx

def sum_of_lists(ls):
    '''Calculates the sum of an input list of lists'''

    s = 0
    for l in ls:
        for val in l:
            s += val

    return s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our main file has to import this function from the test_module.pyx file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#filename: test_cython.py

from test_module import *

#create a list of lists
smallrange = list(range(10000))
inlist = [smallrange,smallrange,smallrange,smallrange]

#now sum them
list_sum = sum_of_lists(inlist)

print(list_sum)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now lets define a setup.py file for compiling our module using Cython:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#filename: setup.py

from setuptools import setup
from Cython.Build import cythonize

setup(
    ext_modules = cythonize("test_module.pyx")
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, its time to compile our module:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python3 setup.py build_ext --inplace
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now lets see how much better this version does compared to the original by timing them 1000 times:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In this case Cython nets us an almost 2X speed-up compared to the original - but this will vary depending on the type of code you are trying to optimize.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6p6nf1lp2ehj7db5bkr9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6p6nf1lp2ehj7db5bkr9.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are looking to take advantage of &lt;strong&gt;Cython&lt;/strong&gt; inside &lt;strong&gt;Jupyter&lt;/strong&gt; notebooks, there is a &lt;strong&gt;%%Cython&lt;/strong&gt; magic available which lets you compile your functions with minimal hassle.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Avoid loops when possible
&lt;/h2&gt;

&lt;p&gt;In many cases using operations like &lt;strong&gt;map&lt;/strong&gt;, &lt;strong&gt;list&lt;/strong&gt; comprehensions or &lt;strong&gt;numpy.vectorize&lt;/strong&gt;(usually the fastest) in python instead of loops can give you a significant performance boost without much work, as these operations are heavily optimized internally. Lets modify our previous example a bit by replacing the nested loops with &lt;strong&gt;map&lt;/strong&gt; and &lt;strong&gt;sum&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#filename: test_map.py

def sum_of_lists_map(ls):
    '''Calculates the sum of an input list of lists'''

    return(sum(list(map(sum,ls))))


#create a list of lists
smallrange = list(range(10000))
inlist = [smallrange,smallrange,smallrange,smallrange]

#now sum them
list_sum = sum_of_lists_map(inlist)

print(list_sum)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lets see how the new map version does compared to the original by timing them 1000 times:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The map version is over 6X faster than the original!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fv8lm10ewq5hpezcb73bp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fv8lm10ewq5hpezcb73bp.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;These were 3 easy to implement tips to net you some extra performance - for more information about &lt;strong&gt;line_profiler&lt;/strong&gt; and &lt;strong&gt;Cython&lt;/strong&gt; in &lt;strong&gt;Jupyter&lt;/strong&gt;, you can check out the &lt;strong&gt;%%lprun&lt;/strong&gt; and &lt;strong&gt;%%cython&lt;/strong&gt; cell magics.&lt;/p&gt;

</description>
      <category>python</category>
      <category>machinelearning</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
