Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit de2755c

Browse files
choldgrafQuLogic
authored andcommitted
Adding an intro tutorial
1 parent 85e52f6 commit de2755c

File tree

1 file changed

+274
-0
lines changed

1 file changed

+274
-0
lines changed
Lines changed: 274 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,274 @@
1+
"""
2+
=======================
3+
The Lifecycle of a Plot
4+
=======================
5+
6+
This tutorial aims to show the beginning, middle, and end of a single
7+
visualization using Matplotlib. We'll begin with some raw data and
8+
end by saving a figure of a customized visualization. Along the way we'll try
9+
to highlight some neat features and best-practices using Matplotlib.
10+
11+
.. currentmodule:: matplotlib
12+
13+
.. note::
14+
15+
This tutorial is based off of
16+
`this excellent blog post <http://pbpython.com/effective-matplotlib.html>`_
17+
by Chris Moffitt. It was transformed into this tutorial by Chris Holdgraf.
18+
19+
A note on the Object-Oriented API vs Pyplot
20+
===========================================
21+
22+
Matplotlib has two interfaces. The first is an object-oriented (OO)
23+
interface. In this case, we utilize an instance of :class:`axes.Axes`
24+
in order to render visualizations on an instance of :class:`figure.Figure`.
25+
26+
The second is based on MATLAB and uses
27+
a state-based interface. This is encapsulated in the :mod:`pyplot`
28+
module. See the :ref:`pyplot tutorials
29+
<sphx_glr_tutorials_01_introductory_pyplot.py>`
30+
for a more in-depth look at the pyplot interface.
31+
32+
Most of the terms are straightforward but the main thing to remember
33+
is that:
34+
35+
* The Figure is the final image that may contain 1 or more Axes.
36+
* The Axes represent an individual plot (don't confuse this with the word
37+
"axis", which refers to the x/y axis of a plot).
38+
39+
We call methods that do the plotting directly from the Axes, which gives
40+
us much more flexibility and power in customizing our plot. See the
41+
:ref:`object-oriented examples <api_examples>` for many examples of how
42+
this approach is used.
43+
44+
.. note::
45+
46+
In general, try to use the object-oriented interface over the pyplot
47+
interface.
48+
49+
Our data
50+
========
51+
52+
We'll use the data from the post from which this tutorial was derived.
53+
It contains sales information for a number of companies.
54+
"""
55+
56+
# sphinx_gallery_thumbnail_number = 10
57+
import numpy as np
58+
import matplotlib.pyplot as plt
59+
from matplotlib.ticker import FuncFormatter
60+
61+
data = {'Barton LLC': 109438.50,
62+
'Frami, Hills and Schmidt': 103569.59,
63+
'Fritsch, Russel and Anderson': 112214.71,
64+
'Jerde-Hilpert': 112591.43,
65+
'Keeling LLC': 100934.30,
66+
'Koepp Ltd': 103660.54,
67+
'Kulas Inc': 137351.96,
68+
'Trantow-Barrows': 123381.38,
69+
'White-Trantow': 135841.99,
70+
'Will LLC': 104437.60}
71+
group_data = list(data.values())
72+
group_names = list(data.keys())
73+
group_mean = np.mean(group_data)
74+
75+
###############################################################################
76+
# Getting started
77+
# ===============
78+
#
79+
# This data is naturally visualized as a barplot, with one bar per
80+
# group. To do this with the object-oriented approach, we'll first generate
81+
# an instance of :class:`figure.Figure` and
82+
# :class:`axes.Axes`. The Figure is like a canvas, and the Axes
83+
# is a part of that canvas on which we will make a particular visualization.
84+
#
85+
# .. note::
86+
#
87+
# Figures can have multiple axes on them. For information on how to do this,
88+
# see the :ref:`Tight Layout tutorial
89+
# <sphx_glr_tutorials_02_intermediate_tight_layout_guide.py>`.
90+
91+
fig, ax = plt.subplots()
92+
93+
###############################################################################
94+
# Now that we have an Axes instance, we can plot on top of it.
95+
96+
fig, ax = plt.subplots()
97+
ax.barh(group_names, group_data)
98+
99+
###############################################################################
100+
# Controlling the style
101+
# =====================
102+
#
103+
# There are many styles available in Matplotlib in order to let you tailor
104+
# your visualization to your needs. To see a list of styles, we can use
105+
# :mod:`pyplot.style`.
106+
107+
print(plt.style.available)
108+
109+
###############################################################################
110+
# You can activate a style with the following:
111+
112+
plt.style.use('fivethirtyeight')
113+
114+
###############################################################################
115+
# Now let's remake the above plot to see how it looks:
116+
117+
fig, ax = plt.subplots()
118+
ax.barh(group_names, group_data)
119+
120+
###############################################################################
121+
# The style controls many things, such as color, linewidths, backgrounds,
122+
# etc.
123+
#
124+
# Customizing the plot
125+
# ====================
126+
#
127+
# Now we've got a plot with the general look that we want, so let's fine-tune
128+
# it so that it's ready for print. First let's rotate the labels on the x-axis
129+
# so that they show up more clearly. We can gain access to these labels
130+
# with the :meth:`axes.Axes.get_xticklabels` method:
131+
132+
fig, ax = plt.subplots()
133+
ax.barh(group_names, group_data)
134+
labels = ax.get_xticklabels()
135+
136+
###############################################################################
137+
# If we'd like to set the property of many items at once, it's useful to use
138+
# the :func:`pyplot.setp` function. This will take a list (or many lists) of
139+
# Matplotlib objects, and attempt to set some style element of each one.
140+
141+
fig, ax = plt.subplots()
142+
ax.barh(group_names, group_data)
143+
labels = ax.get_xticklabels()
144+
plt.setp(labels, rotation=45, horizontalalignment='right')
145+
146+
###############################################################################
147+
# It looks like this cut off some of the labels on the bottom. We can
148+
# tell Matplotlib to automatically make room for elements in the figures
149+
# that we create. To do this we'll set the ``autolayout`` value of our
150+
# rcParams. For more information on controlling the style, layout, and
151+
# other features of plots with rcParams, see
152+
# :ref:`sphx_glr_tutorials_01_introductory_customizing.py`.
153+
154+
plt.rcParams.update({'figure.autolayout': True})
155+
156+
fig, ax = plt.subplots()
157+
ax.barh(group_names, group_data)
158+
labels = ax.get_xticklabels()
159+
plt.setp(labels, rotation=45, horizontalalignment='right')
160+
161+
###############################################################################
162+
# Next, we'll add labels to the plot. To do this with the OO interface,
163+
# we can use the :meth:`axes.Axes.set` method to set properties of this
164+
# Axes object.
165+
166+
fig, ax = plt.subplots()
167+
ax.barh(group_names, group_data)
168+
labels = ax.get_xticklabels()
169+
plt.setp(labels, rotation=45, horizontalalignment='right')
170+
ax.set(xlim=[-10000, 140000], xlabel='Total Revenue', ylabel='Company',
171+
title='Company Revenue')
172+
173+
###############################################################################
174+
# We can also adjust the size of this plot using the :func:`pyplot.subplots`
175+
# function. We can do this with the ``figsize`` kwarg.
176+
#
177+
# .. note::
178+
#
179+
# While indexing in NumPy follows the form (row, column), the figsize
180+
# kwarg follows the form (width, height). This follows conventions in
181+
# visualization, which unfortunately are different from those of linear
182+
# algebra.
183+
184+
fig, ax = plt.subplots(figsize=(8, 4))
185+
ax.barh(group_names, group_data)
186+
labels = ax.get_xticklabels()
187+
plt.setp(labels, rotation=45, horizontalalignment='right')
188+
ax.set(xlim=[-10000, 140000], xlabel='Total Revenue', ylabel='Company',
189+
title='Company Revenue')
190+
191+
###############################################################################
192+
# For labels, we can specify custom formatting guidelines in the form of
193+
# functions by using the :class:`ticker.FuncFormatter` class. Below we'll
194+
# define a function that takes an integer as input, and returns a string
195+
# as an output.
196+
197+
198+
def currency(x, pos):
199+
"""The two args are the value and tick position"""
200+
if x >= 1e6:
201+
s = '${:1.1f}M'.format(x*1e-6)
202+
else:
203+
s = '${:1.0f}K'.format(x*1e-3)
204+
return s
205+
206+
formatter = FuncFormatter(currency)
207+
208+
###############################################################################
209+
# We can then apply this formatter to the labels on our plot. To do this,
210+
# we'll use the ``xaxis`` attribute of our axis. This lets you perform
211+
# actions on a specific axis on our plot.
212+
213+
fig, ax = plt.subplots(figsize=(6, 8))
214+
ax.barh(group_names, group_data)
215+
labels = ax.get_xticklabels()
216+
plt.setp(labels, rotation=45, horizontalalignment='right')
217+
218+
ax.set(xlim=[-10000, 140000], xlabel='Total Revenue', ylabel='Company',
219+
title='Company Revenue')
220+
ax.xaxis.set_major_formatter(formatter)
221+
222+
###############################################################################
223+
# Combining multiple visualizations
224+
# =================================
225+
#
226+
# It is possible to draw multiple plot elements on the same instance of
227+
# :class:`axes.Axes`. To do this we simply need to call another one of
228+
# the plot methods on that axes object.
229+
230+
fig, ax = plt.subplots(figsize=(8, 8))
231+
ax.barh(group_names, group_data)
232+
labels = ax.get_xticklabels()
233+
plt.setp(labels, rotation=45, horizontalalignment='right')
234+
235+
# Add a vertical line, here we set the style in the function call
236+
ax.axvline(group_mean, ls='--', color='r')
237+
238+
# Annotate new companies
239+
for group in [3, 5, 8]:
240+
ax.text(145000, group, "New Company", fontsize=10,
241+
verticalalignment="center")
242+
243+
# Now we'll move our title up since it's getting a little cramped
244+
ax.title.set(y=1.05)
245+
246+
ax.set(xlim=[-10000, 140000], xlabel='Total Revenue', ylabel='Company',
247+
title='Company Revenue')
248+
ax.xaxis.set_major_formatter(formatter)
249+
ax.set_xticks([0, 25e3, 50e3, 75e3, 100e3, 125e3])
250+
fig.subplots_adjust(right=.1)
251+
252+
plt.show()
253+
254+
###############################################################################
255+
# Saving our plot
256+
# ===============
257+
#
258+
# Now that we're happy with the outcome of our plot, we want to save it to
259+
# disk. There are many file formats we can save to in Matplotlib. To see
260+
# a list of available options, use:
261+
262+
print(fig.canvas.get_supported_filetypes())
263+
264+
###############################################################################
265+
# We can then use the :meth:`figure.Figure.savefig` in order to save the figure
266+
# to disk. Note that there are several useful flags we'll show below:
267+
#
268+
# * ``transparent=True`` makes the background of the saved figure transparent
269+
# if the format supports it.
270+
# * ``dpi=80`` controls the resolution (dots per square inch) of the output.
271+
# * ``bbox_inches="tight"`` fits the bounds of the figure to our plot.
272+
273+
# Uncomment this line to save the figure.
274+
# fig.savefig('sales.png', transparent=False, dpi=80, bbox_inches="tight")

0 commit comments

Comments
 (0)