44 < head >
55 < meta charset ="utf-8 ">
66 < meta name ="viewport " content ="width=device-width, initial-scale=1, shrink-to-fit=no ">
7- < meta name ="description " content ="Interactive comparison of Python plotting libraries for exploratory data analysis. Examples of using Pandas plotting, plotnine, Seaborn , and Matplotlib. Includes comparison with ggplot2 for R . ">
7+ < meta name ="description " content ="Side-by-side comparison of Python plotting libraries for exploratory data analysis: pandas, Matplotlib, Seaborn, plotnine, Lets-Plot, plotly, hvPlot , and Altair, with R's ggplot2 for reference . ">
88 < meta name ="author " content ="Timothy Hopper ">
99
1010 < title > Python Plotting for Exploratory Analysis</ title >
1111
12+ < link rel ="canonical " href ="https://pythonplot.com/ ">
13+
1214 < meta property ="og:title " content ="Python Plotting for Exploratory Analysis " />
1315 < meta property ="og:type " content ="article " />
14- < meta property ="og:url " content ="https://pythonplot.com " />
15- < meta property ="og:image " content ="http://pythonplot.com/img/cover.png " />
16+ < meta property ="og:site_name " content ="pythonplot.com " />
17+ < meta property ="og:url " content ="https://pythonplot.com/ " />
18+ < meta property ="og:image " content ="https://pythonplot.com/img/banner.png " />
19+ < meta property ="og:image:alt " content ="The same plot drawn with several Python plotting libraries side by side. " />
1620 < meta property ="og:description "
17- content ="Interactive comparison of Python plotting libraries for exploratory data analysis. Examples of using Pandas plotting, plotnine, Seaborn , and Matplotlib. Includes comparison with ggplot2 for R . " />
18- < meta name ="twitter:card " content ="summary " />
21+ content ="Side-by-side comparison of Python plotting libraries for exploratory data analysis: pandas, Matplotlib, Seaborn, plotnine, Lets-Plot, plotly, hvPlot , and Altair, with R's ggplot2 for reference . " />
22+ < meta name ="twitter:card " content ="summary_large_image " />
1923 < meta name ="twitter:site " content ="@tdhopper " />
2024 < meta name ="twitter:creator " content ="@tdhopper " />
25+ < meta name ="twitter:title " content ="Python Plotting for Exploratory Analysis " />
26+ < meta name ="twitter:description "
27+ content ="Side-by-side comparison of Python plotting libraries for exploratory data analysis: pandas, Matplotlib, Seaborn, plotnine, Lets-Plot, plotly, hvPlot, and Altair, with R's ggplot2 for reference. " />
28+ < meta name ="twitter:image " content ="https://pythonplot.com/img/banner.png " />
2129
2230 < link rel ="apple-touch-icon " sizes ="57x57 " href ="/img/ico/apple-icon-57x57.png ">
2331 < link rel ="apple-touch-icon " sizes ="60x60 " href ="/img/ico/apple-icon-60x60.png ">
7482
7583 < div class ="container ">
7684
77- < div class ="row "> < div class ="col-xs- 12 col-lg-6 col-md-8 offset-md-1 offset-lg-2 ">
85+ < div class ="row "> < div class ="col-12 col-lg-6 col-md-8 offset-md-1 offset-lg-2 ">
7886 < img class ="img-fluid pb-4 " src ="/img/banner.png ">
7987 < h1 > Python Plotting for Exploratory Data Analysis</ h1 >
8088
@@ -96,7 +104,7 @@ <h3>Contents</h3>
96104 </ div >
97105 </ div >
98106
99- < div class ="row "> < div class ="col-xs- 12 col-lg-8 col-md-8 offset-md-1 offset-lg-2 ">
107+ < div class ="row "> < div class ="col-12 col-lg-8 col-md-8 offset-md-1 offset-lg-2 ">
100108 {% for name, table in data.items() %}
101109 < h5 > {{ name }}</ h5 >
102110
@@ -105,17 +113,17 @@ <h5>{{ name }}</h5>
105113 </ div > </ div >
106114
107115 < hr >
108- < div class ="row mt-4 " id ="examples "> < div class ="col-xs- 12 col-md-10 offset-md-1 ">
116+ < div class ="row mt-4 " id ="examples "> < div class ="col-12 col-md-10 offset-md-1 ">
109117 {% for (name, slug), items in plots.items() %}
118+ {% set outer_loop = loop %}
110119 < section id ="{{ slug }} ">
111120 < div class ="card mb-4 ">
112121 < div class ="card-header ">
113- < h3 class ="card-title mb-1 "> < a href ="#{{ slug }} "> < i class =" fa fa-link " aria-hidden =" true " > </ i > </ a > {{ name }}</ h3 >
114- < ul class ="nav nav-tabs card-header-tabs ">
122+ < h3 class ="card-title mb-1 "> {{ name }} < a class =" anchor-link " href ="#{{ slug }} " title =" Link to {{ name }} " aria-label =" Link to {{ name }}" > # </ a > </ h3 >
123+ < ul class ="nav nav-pills card-header-pills library-pills ">
115124 {% for plot in items %}
116125 < li class ="nav-item ">
117- < a class ="nav-link {% if loop.index0 == 0 %} active{% endif %} " data-toggle ="tab " href ="#{{ slug }}{{ plot['package-slug'] }} " role ="tab "> {{ plot['package'] }}
118- </ a >
126+ < a class ="nav-link{% if loop.index0 == 0 %} active{% endif %} " data-toggle ="tab " href ="#{{ slug }}{{ plot['package-slug'] }} " role ="tab "> {{ plot['package'] }}</ a >
119127 </ li >
120128 {% endfor %}
121129 </ ul >
@@ -124,17 +132,21 @@ <h3 class="card-title mb-1"><a href="#{{ slug }}"><i class="fa fa-link" aria-hid
124132 < div class ="card-block p-0 ">
125133 < div class ="tab-content ">
126134 {% for plot in items %}
135+ {% set eager = outer_loop.first and loop.first %}
127136 < div class ="tab-pane {% if loop.index0 == 0 %} active{% endif %} " id ="{{ slug }}{{ plot['package-slug'] }} " role ="tabpanel ">
128137 < div class ="container-fluid ">
129138 < div class ="row ">
130- < div class ="col-lg-6 col-xs- 12 p-lg-0 ">
139+ < div class ="col-lg-6 col-12 p-lg-0 ">
131140 < a href ="{{ plot['image'] }} " data-toggle ="lightbox " data-title ="{{ name }} - {{ plot['package'] }} ">
132- < img src ="{{ plot['image'] }} " class ="img-fluid ">
141+ < img src ="{{ plot['image'] }} " class ="img-fluid " alt =" {{ name }} drawn with {{ plot['package'] }} " width =" {{ plot['image-width'] }} " height =" {{ plot['image-height'] }} " decoding =" async " {% if not eager %} loading =" lazy " {% endif %} >
133142 </ a >
134143 </ div >
135- < div class ="col-lg-6 col-xs-12 p-0 right-col d-inline-flex flex-column ">
136- < h6 class ="text-muted mb-0 pb-0 pt-3 px-3 "> Code:</ h6 >
137- {% if plot['package'] == "ggplot" %}
144+ < div class ="col-lg-6 col-12 p-0 right-col d-inline-flex flex-column ">
145+ < div class ="code-head d-flex justify-content-between align-items-center pt-3 px-3 ">
146+ < h6 class ="text-muted mb-0 pb-0 "> Code:</ h6 >
147+ < button type ="button " class ="copy-btn " data-copy aria-label ="Copy code for {{ name }} with {{ plot['package'] }} "> Copy</ button >
148+ </ div >
149+ {% if plot['package-slug'] == "ggplot" %}
138150 < code class ="p-0 mb-auto "> {% highlight 'R' %}{{ plot['content'] }}{% endhighlight %}</ code >
139151 {% else %}
140152 < code class ="p-0 mb-auto "> {% highlight 'python' %}{{ plot['content'] }}{% endhighlight %}</ code >
@@ -179,7 +191,30 @@ <h6 class="text-muted">Note:</h6>
179191 event . preventDefault ( ) ;
180192 $ ( this ) . ekkoLightbox ( { alwaysShowClose : true } ) ;
181193 } ) ;
182- $ . bigfoot ( ) ;
194+ </ script >
195+
196+ < script type ="text/javascript ">
197+ document . addEventListener ( 'click' , function ( event ) {
198+ var button = event . target . closest ( '[data-copy]' ) ;
199+ if ( ! button ) { return ; }
200+ var panel = button . closest ( '.right-col' ) ;
201+ var code = panel && panel . querySelector ( 'code' ) ;
202+ if ( ! code ) { return ; }
203+ var text = code . textContent . replace ( / \s + $ / , '' ) ;
204+ var done = function ( label ) {
205+ button . textContent = label ;
206+ setTimeout ( function ( ) { button . textContent = 'Copy' ; } , 1500 ) ;
207+ } ;
208+ if ( navigator . clipboard && navigator . clipboard . writeText ) {
209+ navigator . clipboard . writeText ( text ) . then ( function ( ) {
210+ done ( 'Copied' ) ;
211+ } , function ( ) {
212+ done ( 'Press ⌘C' ) ;
213+ } ) ;
214+ } else {
215+ done ( 'Press ⌘C' ) ;
216+ }
217+ } ) ;
183218 </ script >
184219 </ body >
185220</ html >
0 commit comments