File: introduction.ipynb

package info (click to toggle)
seaborn 0.9.0-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 2,124 kB
  • sloc: python: 18,293; makefile: 171; sh: 2
file content (543 lines) | stat: -rw-r--r-- 24,808 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
{
 "cells": [
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    ".. _introduction:\n",
    "\n",
    ".. currentmodule:: seaborn\n",
    "\n",
    "An introduction to seaborn\n",
    "==========================\n",
    "\n",
    ".. raw:: html\n",
    "\n",
    "   <div class=col-md-9>\n",
    "\n",
    "Seaborn is a library for making statistical graphics in Python. It is built on top of `matplotlib <https://matplotlib.org/>`_ and closely integrated with `pandas <https://pandas.pydata.org/>`_ data structures.\n",
    "\n",
    "Here is some of the functionality that seaborn offers:\n",
    "\n",
    "- A dataset-oriented API for examining :ref:`relationships <scatter_bubbles>` between :ref:`multiple variables <faceted_lineplot>`\n",
    "- Specialized support for using categorical variables to show :ref:`observations <jitter_stripplot>` or :ref:`aggregate statistics <pointplot_anova>` \n",
    "- Options for visualizing :ref:`univariate <distplot_options>` or :ref:`bivariate <joint_kde>` distributions and for :ref:`comparing <horizontal_boxplot>` them between subsets of data\n",
    "- Automatic estimation and plotting of :ref:`linear regression <anscombes_quartet>` models for different kinds :ref:`dependent <logistic_regression>` variables\n",
    "- Convenient views onto the overall :ref:`structure <scatterplot_matrix>` of complex datasets\n",
    "- High-level abstractions for structuring :ref:`multi-plot grids <faceted_histogram>` that let you easily build :ref:`complex <pair_grid_with_kde>` visualizations\n",
    "- Concise control over matplotlib figure styling with several :ref:`built-in themes <aesthetics_tutorial>`\n",
    "- Tools for choosing :ref:`color palettes <palette_tutorial>` that faithfully reveal patterns in your data\n",
    "\n",
    "Seaborn aims to make visualization a central part of exploring and understanding data. Its dataset-oriented plotting functions operate on dataframes and arrays containing whole datasets and internally perform the necessary semantic mapping and statistical aggregation to produce informative plots.\n",
    "\n",
    "Here's an example of what this means:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "hide"
    ]
   },
   "outputs": [],
   "source": [
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import seaborn as sns\n",
    "sns.set()\n",
    "tips = sns.load_dataset(\"tips\")\n",
    "sns.relplot(x=\"total_bill\", y=\"tip\", col=\"time\",\n",
    "            hue=\"smoker\", style=\"smoker\", size=\"size\",\n",
    "            data=tips);"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "A few things have happened here. Let's go through them one by one:\n",
    "\n",
    "1. We import seaborn, which is the only library necessary for this simple example."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "hide-output"
    ]
   },
   "outputs": [],
   "source": [
    "import seaborn as sns"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "Behind the scenes, seaborn uses matplotlib to draw plots. Many tasks can be accomplished with only seaborn functions, but further customization might require using matplotlib directly. This is explained in more detail :ref:`below <intro_plot_customization>`. For interactive work, it's recommended to use a Jupyter/IPython interface in `matplotlib mode <https://ipython.readthedocs.io/en/stable/interactive/plotting.html>`_, or else you'll have to call :ref:`matplotlib.pyplot.show` when you want to see the plot.\n",
    "\n",
    "2. We apply the default default seaborn theme, scaling, and color palette."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "hide-output"
    ]
   },
   "outputs": [],
   "source": [
    "sns.set()"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "This uses the `matplotlib rcParam system <https://matplotlib.org/users/customizing.html>`_ and will affect how all matplotlib plots look, even if you don't make them with seaborn. Beyond the default theme, there are :ref:`several other options <aesthetics_tutorial>`, and you can independently control the style and scaling of the plot to quickly translate your work between presentation contexts (e.g., making a plot that will have readable fonts when projected during a talk). If you like the matplotlib defaults or prefer a different theme, you can skip this step and still use the seaborn plotting functions.\n",
    "\n",
    "3. We load one of the example datasets."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "hide-output"
    ]
   },
   "outputs": [],
   "source": [
    "tips = sns.load_dataset(\"tips\")"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "Most code in the docs will use the :func:`load_dataset` function to get quick access to an example dataset. There's nothing particularly special about these datasets; they are just pandas dataframes, and we could have loaded them with :ref:`pandas.read_csv` or build them by hand. Many examples use the \"tips\" dataset, which is very boring but quite useful for demonstration. The tips dataset illustrates the \"tidy\" approach to organizing a dataset. You'll get the most out of seaborn if your datasets are organized this way, and it is explained in more detail :ref:`below <intro_tidy_data>`.\n",
    "\n",
    "4. We draw a faceted scatter plot with multiple semantic variables."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": [
     "hide-output"
    ]
   },
   "outputs": [],
   "source": [
    "sns.relplot(x=\"total_bill\", y=\"tip\", col=\"time\",\n",
    "            hue=\"smoker\", style=\"smoker\", size=\"size\",\n",
    "            data=tips)"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "This particular plot shows the relationship between five variables in the tips dataset. Three are numeric, and two are categorical. Two numeric variables (``total_bill`` and ``tip``) determined the position of each point on the axes, and the third (``size``) determined the size of each point. One categorical variable split the dataset onto two different axes (facets), and the other determined the color and shape of each point.\n",
    "\n",
    "All of this was accomplished using a single call to the seaborn function :func:`relplot`. Notice how we only provided the names of the variables in the dataset and the roles that we wanted them to play in the plot. Unlike when using matplotlib directly, it wasn't necessary to translate the variables into parameters of the visualization (e.g., the specific color or marker to use for each category). That translation was done automatically by seaborn. This lets the user stay focused on the question they want the plot to answer.\n",
    "\n",
    ".. _intro_api_abstraction:\n",
    "\n",
    "API abstraction across visualizations\n",
    "-------------------------------------\n",
    "\n",
    "There is no universal best way to visualize data. Different questions are best answered by different kinds of visualizations. Seaborn tries to make it easy to switch between different visual representations that can be parameterized with the same dataset-oriented API.\n",
    "\n",
    "The function :func:`relplot` is named that way because it is designed to visualize many different statistical *relationships*. While scatter plots are a highly effective way of doing this, relationships where one variable represents a measure of time are better represented by a line. The :func:`relplot` function has a convenient ``kind`` parameter to let you easily switch to this alternate representation:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "dots = sns.load_dataset(\"dots\")\n",
    "sns.relplot(x=\"time\", y=\"firing_rate\", col=\"align\",\n",
    "            hue=\"choice\", size=\"coherence\", style=\"choice\",\n",
    "            facet_kws=dict(sharex=False),\n",
    "            kind=\"line\", legend=\"full\", data=dots);"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "Notice how the ``size`` and ``style`` parameters are shared across the scatter and line plots, but they affect the two visualizations differently (changing marker area and symbol vs line width and dashing). We did not need to keep those details in mind, letting us focus on the overall structure of the plot and the information we want it to convey.\n",
    "\n",
    ".. _intro_stat_estimation:\n",
    "\n",
    "Statistical estimation and error bars\n",
    "-------------------------------------\n",
    "\n",
    "Often we are interested in the average value of one variable as a function of other variables. Many seaborn functions can automatically perform the statistical estimation that is neccesary to answer these questions:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fmri = sns.load_dataset(\"fmri\")\n",
    "sns.relplot(x=\"timepoint\", y=\"signal\", col=\"region\",\n",
    "            hue=\"event\", style=\"event\",\n",
    "            kind=\"line\", data=fmri);"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "When statistical values are estimated, seaborn will use bootstrapping to compute confidence intervals and draw error bars representing the uncertainty of the estimate.\n",
    "\n",
    "Statistical estimation in seaborn goes beyond descriptive statisitics. For example, it is also possible to enhance a scatterplot to include a linear regression model (and its uncertainty) using :func:`lmplot`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.lmplot(x=\"total_bill\", y=\"tip\", col=\"time\", hue=\"smoker\",\n",
    "           data=tips);"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    ".. _intro_categorical:\n",
    "\n",
    "Specialized categorical plots\n",
    "-----------------------------\n",
    "\n",
    "Standard scatter and line plots visualize relationships between numerical variables, but many data analyses involve categorical variables. There are several specialized plot types in seaborn that are optimized for visualizing this kind of data. They can be accessed through :func:`catplot`. Similar to :func:`relplot`, the idea of :func:`catplot` is that it exposes a common dataset-oriented API that generalizes over different representations of the relationship between one numeric variable and one (or more) categorical variables.\n",
    "\n",
    "These representations offer different levels of granularity in their presentation of the underlying data. At the finest level, you may wish to see every observation by drawing a scatter plot that adjusts the positions of the points along the categorical axis so that they don't overlap:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.catplot(x=\"day\", y=\"total_bill\", hue=\"smoker\",\n",
    "            kind=\"swarm\", data=tips);"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "Alternately, you could use kernel density estimation to represent the underlying distribution that the points are sampled from:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.catplot(x=\"day\", y=\"total_bill\", hue=\"smoker\",\n",
    "            kind=\"violin\", split=True, data=tips);"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "Or you could show the only mean value and its confidence interval within each nested category:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.catplot(x=\"day\", y=\"total_bill\", hue=\"smoker\",\n",
    "            kind=\"bar\", data=tips);"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    ".. _intro_func_types:\n",
    "\n",
    "Figure-level and axes-level functions\n",
    "-------------------------------------\n",
    "\n",
    "How do these tools work? It's important to know about a major distinction between seaborn plotting functions. All of the plots shown so far have been made with \"figure-level\" functions. These are optimized for exploratory analysis because they set up the matplotlib figure containing the plot(s) and make it easy to spread out the visualization across multiple axes. They also handle some tricky business like putting the legend outside the axes. To do these things, they use a seaborn :class:`FacetGrid`.\n",
    "\n",
    "Each different figure-level plot ``kind`` combines a particular \"axes-level\" function with the :class:`FacetGrid` object. For example, the scatter plots are drawn using the :func:`scatterplot` function, and the bar plots are drawn using the :func:`barplot` function. These functions are called \"axes-level\" because they draw onto a single matplotlib axes and don't otherwise affect the rest of the figure.\n",
    "\n",
    "The upshot is that the figure-level function needs to control the figure it lives in, while axes-level functions can be combined into a more complex matplotlib figure with other axes that may or may not have seaborn plots on them:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "f, axes = plt.subplots(1, 2, sharey=True, figsize=(6, 4))\n",
    "sns.boxplot(x=\"day\", y=\"tip\", data=tips, ax=axes[0])\n",
    "sns.scatterplot(x=\"total_bill\", y=\"tip\", hue=\"day\", data=tips, ax=axes[1]);"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "Controling the size of the figure-level functions works a little bit differently than it does for other matplotlib figures. Instead of setting the overall figure size, the figure-level functions are parameterized by the size of each facet. And instead of setting the height and width of each facet, you control the height and *aspect* ratio (ratio of width to height). This parameterization makes it easy to control the size of the graphic without thinking about exactly how many rows and columns it will have, although it can be a source of confusion:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.relplot(x=\"time\", y=\"firing_rate\", col=\"align\",\n",
    "            hue=\"choice\", size=\"coherence\", style=\"choice\",\n",
    "            height=4.5, aspect=2 / 3,\n",
    "            facet_kws=dict(sharex=False),\n",
    "            kind=\"line\", legend=\"full\", data=dots);"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "The way you can tell whether a function is \"figure-level\" or \"axes-level\" is whether it takes an ``ax=`` parameter. You can also distinguish the two classes by their output type: axes-level functions return the matplotlib ``axes``, while figure-level functions return the :class:`FacetGrid`.\n",
    "\n",
    "\n",
    ".. _intro_dataset_funcs:\n",
    "\n",
    "Visualizing dataset structure\n",
    "-----------------------------\n",
    "\n",
    "There are two other kinds of figure-level functions in seaborn that can be used to make visualizations with multiple plots. They are each oriented towards illuminating the structure of a dataset. One, :func:`jointplot`, focuses on a single relationship:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "iris = sns.load_dataset(\"iris\")\n",
    "sns.jointplot(x=\"sepal_length\", y=\"petal_length\", data=iris);"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "The other, :func:`pairplot`, takes a broader view, showing all pairwise relationships and the marginal distributions, optionally conditioned on a categorical variable :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.pairplot(data=iris, hue=\"species\");"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "Both :func:`jointplot` and :func:`pairplot` have a few different options for visual representation, and they are built on top of classes that allow more thoroughly customized multi-plot figures (:class:`JointGrid` and :class:`PairGrid`, respectively).\n",
    "\n",
    ".. _intro_plot_customization:\n",
    "\n",
    "Customizing plot appearance\n",
    "---------------------------\n",
    "\n",
    "The plotting functions try to use good default aesthetics and add informative labels so that their output is immediately useful. But defaults can only go so far, and creating a fully-polished custom plot will require additional steps. Several levels of additional customization are possible. \n",
    "\n",
    "The first way is to use one of the alternate seaborn themes to give your plots a different look. Setting a different theme or color palette will make it take effect for all plots:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.set(style=\"ticks\", palette=\"muted\")\n",
    "sns.relplot(x=\"total_bill\", y=\"tip\", col=\"time\",\n",
    "            hue=\"smoker\", style=\"smoker\", size=\"size\",\n",
    "            data=tips);"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "For figure-specific customization, all seaborn functions accept a number of optional parameters for switching to non-default semantic mappings, such as different colors. (Appropriate use of color is critical for effective data visualization, and seaborn has :ref:`extensive support <palette_tutorial>` for customizing color palettes).\n",
    "\n",
    "Finally, where there is a direct correspondence with an underlying matplotlib function (like :func:`scatterplot` and ``plt.scatter``), additional keyword arguments will be passed through to the matplotlib layer:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.relplot(x=\"total_bill\", y=\"tip\", col=\"time\",\n",
    "            hue=\"size\", style=\"smoker\", size=\"size\",\n",
    "            palette=\"YlGnBu\", markers=[\"D\", \"o\"], sizes=(10, 125),\n",
    "            edgecolor=\".2\", linewidth=.5, alpha=.75,\n",
    "            data=tips);"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "In the case of :func:`relplot` and other figure-level functions, that means there are a few levels of indirection because :func:`relplot` passes its exta keyword arguments to the underlying seaborn axes-level function, which passes *its* extra keyword arguments to the underlying matplotlib function. So it might take some effort to find the right documentation for the parameters you'll need to use, but in principle an extremely high level of customization is possible.\n",
    "\n",
    "Some customization of figure-level functions can be accomplished through additional parameters that get passed to :class:`FacetGrid`, and you can use the methods on that object to control many other properties of the figure. For even more tweaking, you can access the matplotlib objects that the plot is drawn onto, which are stored as attributes:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "g = sns.catplot(x=\"total_bill\", y=\"day\", hue=\"time\",\n",
    "                height=3.5, aspect=1.5,\n",
    "                kind=\"box\", legend=False, data=tips);\n",
    "g.add_legend(title=\"Meal\")\n",
    "g.set_axis_labels(\"Total bill ($)\", \"\")\n",
    "g.set(xlim=(0, 60), yticklabels=[\"Thursday\", \"Friday\", \"Saturday\", \"Sunday\"])\n",
    "g.despine(trim=True)\n",
    "g.fig.set_size_inches(6.5, 3.5)\n",
    "g.ax.set_xticks([5, 15, 25, 35, 45, 55], minor=True);\n",
    "plt.setp(g.ax.get_yticklabels(), rotation=30);"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "Because the figure-level functions are oriented towards efficient exploration, using them to manage a figure that you need to be precisely sized and organized may take more effort than setting up the figure directly in matplotlib and using the corresponding axes-level seaborn function. Matplotlib has a comprehensive and powerful API; just about any attribute of the figure can be changed to your liking. The hope is that a combination of seaborn's high-level interface and matplotlib's deep customizability will allow you to quickly explore your data and create graphics that can be tailored into a `publication quality <https://github.com/wagnerlabpapers/Waskom_PNAS_2017>`_ final product.\n",
    "\n",
    ".. _intro_tidy_data:\n",
    "\n",
    "Organizing datasets\n",
    "-------------------\n",
    "\n",
    "As mentioned above, seaborn will be most powerful when your datasets have a particular organization. This format ia alternately called \"long-form\" or \"tidy\" data and is described in detail by Hadley Wickham in this `academic paper <http://vita.had.co.nz/papers/tidy-data.html>`_. The rules can be simply stated:\n",
    "\n",
    "1. Each variable is a column\n",
    "2. Each observation is a row\n",
    "\n",
    "A helpful mindset for determining whether your data are tidy is to think backwards from the plot you want to draw. From this perspective, a \"variable\" is something that will be assigned a role in the plot. It may be useful to look at the example datasets and see how they are structured. For example, the first five rows of the \"tips\" dataset look like this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "tips.head()"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "In some domains, the tidy format might feel awkward at first. Timeseries data, for example, are sometimes stored with every timepoint as part of the same observational unit and appearing in the columns. The \"fmri\" dataset that we used :ref:`above <intro_stat_estimation>` illustrates how a tidy timeseries dataset has each timepoint in a different row:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fmri.head()"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "Many seaborn functions can plot wide-form data, but only with limited functionality. To take advantage of the features that depend on tidy-formatted data, you'll likely find the ``pandas.melt`` function useful for \"un-pivoting\" a wide-form dataframe. More information and useful examples can be found `in this blog post <https://tomaugspurger.github.io/modern-5-tidy.html>`_ by one of the pandas developers.\n",
    "\n",
    ".. _intro_next_steps:\n",
    "\n",
    "Next steps\n",
    "----------\n",
    "\n",
    "You have a few options for where to go next. You might first want to learn how to :ref:`install seaborn <installing>`. Once that's done, you can browse the :ref:`example gallery <example_gallery>` to get a broader sense for what kind of graphics seaborn can produce. Or you can read through the :ref:`official tutorial <tutorial>` for a deeper discussion of the different tools and what they are designed to accomplish. If you have a specific plot in mind and want to know how to make it, you could check out the :ref:`API reference <api_ref>`, which documents each function's parameters and shows many examples to illustrate usage."
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    ".. raw:: html\n",
    "   \n",
    "   </div>"
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "Tags",
  "kernelspec": {
   "display_name": "Python 3.6  (seaborn-dev)",
   "language": "python",
   "name": "seaborn-dev"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}