jason246 发表于 2023-3-21 18:22:32

【编程】学习Python绘图库Matplotlib

<style>
        blockquote {margin-left:1em; color:#000080;} /*navy*/
      .bdDiv img { width:100%;max-width:600px;height:auto;}
      .bdDiv h2 {color: #4682B4;}   /*steelblue*/
</style>


<img src="https://tongyici.net:5556/static/data/math/matplotlib/mhtBF30(1).png" style="width:100%;max-width:100%;height:auto;">

<div class="bdDiv">

<br>
<h2 id="#1.-Introduction">1. Introduction</h2>
<p>Matplotlib is the most popular plotting library in python. Using matplotlib,
you can create pretty much any type of plot. However, as your plots get more
complex, the learning curve can get steeper.</p>
<p>The goal of this tutorial is to make you understand ‘how plotting with
matplotlib works’ and make you comfortable to build full-featured plots with
matplotlib.</p>

<br>
<h2 id="#2.-A-Basic-Scatterplot">2. A Basic Scatterplot</h2>
<p>The following piece of code is found in pretty much any python code that has
matplotlib plots.</p><pre><code class="python language-python">import matplotlib.pyplot as plt
%matplotlib inline
</code></pre>
<p><code>matplotlib.pyplot</code> is usually imported as <code>plt</code>. It is
the core object that contains the methods to create all sorts of charts and
features in a plot.</p>
<p>The <code>%matplotlib inline</code> is a <a href="http://jupyter-notebook-beginner-guide.readthedocs.io/en/latest/what_is_jupyter.html"

rel="noopener" target="_blank">jupyter notebook</a> specific command that let’s you
see the plots in the notbook itself.</p>
<p>Suppose you want to draw a specific type of plot, say a scatterplot, the
first thing you want to check out are the methods under <code>plt</code> (type
<code>plt</code> and hit tab or type <code>dir(plt)</code> in python
prompt).</p>
<p>Let’s begin by making a simple but full-featured scatterplot and take it from
there. Let’s see what <code>plt.plot()</code> creates if you an arbitrary
sequence of numbers.</p><pre><code class="python language-python">import matplotlib.pyplot as plt
%matplotlib inline

# Plot
plt.plot()
#&gt; [&lt;matplotlib.lines.Line2D at 0x10edbab70&gt;]
</code></pre>
<img class="aligncenter size-shareaholic-thumbnail wp-image-1816" alt="Matplotlib line plot"

src="https://tongyici.net:5556/static/data/math/matplotlib/01_Matplotlib_line_plot-min.png" >
<p>I just gave a list of numbers to <code>plt.plot()</code> and it drew a line
chart automatically. It assumed the values of the X-axis to start from zero
going up to as many items in the data.</p>
<p>Notice the line <code>matplotlib.lines.Line2D</code> in code output?</p>
<p>That’s because Matplotlib returns the plot object itself besides drawing the
plot.</p>
<p>If you only want to see the plot, add <code>plt.show()</code> at the end and
execute all the lines in one shot.</p>
<p>Alright, notice instead of the intended scatter plot, <code>plt.plot</code>
drew a line plot. That’s because of the default behaviour.</p>
<p>So how to draw a scatterplot instead?</p>
<p>Well to do that, let’s understand a bit more about what arguments
<code>plt.plot()</code> expects. The <code>plt.plot</code> accepts 3 basic
arguments in the following order: <strong>(x, y, format). </strong></p>
<p>This format is a short hand combination of
<code>{color}{marker}{line}</code>.</p>
<p>For example, the format <code>'go-'</code> has 3 characters standing for:
‘green colored dots with solid line’. By omitting the line part (‘-‘) in the
end, you will be left with only green dots (‘go’), which makes it draw a
scatterplot.</p>
<p>Few commonly used short hand format examples are:<br>* <code>'r*--'</code> :
‘red stars with dashed lines’<br>* <code>'ks.'</code> : ‘black squares with
dotted line’ (‘k’ stands for black)<br>* <code>'bD-.'</code> : ‘blue diamonds
with dash-dot line’.</p>
<p>For a complete list of colors, markers and linestyles, check out the
<code>help(plt.plot)</code> command.</p>
<p>Let’s draw a scaterplot with greendots.</p><pre><code class="python language-python"># 'go' stands for green dots
plt.plot(, , 'go')
plt.show()
</code></pre>
<img class="aligncenter size-shareaholic-thumbnail wp-image-1817" alt="Matplotlib scatterplot"

src="https://tongyici.net:5556/static/data/math/matplotlib/02_Matplotlib_scatterplot-min.png" >

<br>
<h2 id="#3.-How-to-draw-two-sets-of-scatterplots-in-same-plot">3. How to draw two
sets of scatterplots in same plot</h2>
<p>Good. Now how to plot another set of 5 points of different color in the same
figure?</p>
<p>Simply call plt.plot() again, it will add those point to the same
picture.</p>
<p>You might wonder, why it does not draw these points in a new panel
altogether? I will come to that in the next section.</p><pre><code class="python language-python"># Draw two sets of points
plt.plot(, , 'go')# green dots
plt.plot(, , 'b*')# blue stars
plt.show()
</code></pre>
<img class="aligncenter size-large wp-image-1818" alt="Matplotlib double scatterplot"

src="https://tongyici.net:5556/static/data/math/matplotlib/03_Matplotlib_double_scatterplot-min.png" >
<p>Looks good. Now let’s add the basic plot features: Title, Legend, X and Y
axis labels. How to do that?</p>
<p>The <code>plt</code> object has corresponding methods to add each of
this.</p><pre><code class="python language-python">plt.plot(, , 'go', label='GreenDots')
plt.plot(, , 'b*', label='Bluestars')
plt.title('A Simple Scatterplot')
plt.xlabel('X')
plt.ylabel('Y')
plt.legend(loc='best')# legend text comes from the plot's label parameter.
plt.show()
</code></pre>
<img class="aligncenter size-shareaholic-thumbnail wp-image-1819" alt=""

src="https://tongyici.net:5556/static/data/math/matplotlib/04_Matplotlib_scatterplot_with_legend-min.png" >
<p>Good. Now, how to increase the size of the plot? (The above plot would
actually look small on a jupyter notebook)</p>
<p>The easy way to do it is by setting the <code>figsize</code> inside
<code>plt.figure()</code> method.</p><pre><code class="python language-python">plt.figure(figsize=(10,7)) # 10 is width, 7 is height
plt.plot(, , 'go', label='GreenDots')# green dots
plt.plot(, , 'b*', label='Bluestars')# blue stars
plt.title('A Simple Scatterplot')
plt.xlabel('X')
plt.ylabel('Y')
plt.xlim(0, 6)
plt.ylim(0, 12)
plt.legend(loc='best')
plt.show()
</code></pre>
<img class="aligncenter size-large wp-image-1820" alt="Matplotlib scatterplot large"

src="https://tongyici.net:5556/static/data/math/matplotlib/05_Matplotlib_scatterplot_large-min.png" >
<p>Ok, we have some new lines of code there. What does <code>plt.figure</code>
do?</p>
<p>Well, every plot that <code>matplotlib</code> makes is drawn on something
called <code>'figure'</code>. You can think of the <code>figure</code> object as
a canvas that holds all the subplots and other plot elements inside it.</p>
<p>And a figure can have one or more subplots inside it called
<code>axes</code>, arranged in rows and columns. Every figure has atleast one
axes. (Don’t confuse this <code>axes</code> with X and Y axis, they are
different.)</p>

<br>
<h2 id="#4.-How-to-draw-2-scatterplots-in-different-panels">4. How to draw 2
scatterplots in different panels</h2>
<p>Let’s understand <code>figure</code> and <code>axes</code> in little more
detail.</p>
<p>Suppose, I want to draw our two sets of points (green rounds and blue stars)
in two separate plots side-by-side instead of the same plot. How would you do
that?</p>
<p>You can do that by creating two separate subplots, aka, <code>axes</code>
using <code>plt.subplots(1, 2)</code>. This creates and returns two
objects:<br>* the figure<br>* the axes (subplots) inside the figure</p>
<img class="aligncenter size-medium wp-image-1844" alt="Matplotlib Structure"

src="https://tongyici.net:5556/static/data/math/matplotlib/99_matplotlib_structure-1.png" >
<p>Previously, I called <code>plt.plot()</code> to draw the points. Since there
was only one axes by default, it drew the points on that axes itself.</p>
<p>But now, since you want the points drawn on different subplots (axes), you
have to call the plot function in the respective axes (<code>ax1</code> and
<code>ax2</code> in below code) instead of <code>plt</code>.</p>
<p>Notice in below code, I call <code>ax1.plot()</code> and
<code>ax2.plot()</code> instead of calling <code>plt.plot()</code> twice.</p><pre><code class="python language-python"># Create Figure and

Subplots
fig, (ax1, ax2) = plt.subplots(1,2, figsize=(10,4), sharey=True, dpi=120)

# Plot
ax1.plot(, , 'go')# greendots
ax2.plot(, , 'b*')# bluestart

# Title, X and Y labels, X and Y Lim
ax1.set_title('Scatterplot Greendots'); ax2.set_title('Scatterplot Bluestars')
ax1.set_xlabel('X');ax2.set_xlabel('X')# x label
ax1.set_ylabel('Y');ax2.set_ylabel('Y')# y label
ax1.set_xlim(0, 6) ;ax2.set_xlim(0, 6)   # x axis limits
ax1.set_ylim(0, 12);ax2.set_ylim(0, 12)# y axis limits

# ax2.yaxis.set_ticks_position('none')
plt.tight_layout()
plt.show()
</code></pre>
<img class="aligncenter size-shareaholic-thumbnail wp-image-1821" alt="Matplotlib double scatterplot"

src="https://tongyici.net:5556/static/data/math/matplotlib/06_Matplotlib_double_scatterplot-min.png" >
<p>Setting <code>sharey=True</code> in <code>plt.subplots()</code> shares the Y
axis between the two subplots.</p>
<p>And <code>dpi=120</code> increased the number of dots per inch of the plot to
make it look more sharp and clear. You will notice a distinct improvement in
clarity on increasing the <code>dpi</code> especially in jupyter notebooks.</p>
<p>Thats sounds like a lot of functions to learn. Well it’s quite easy to
remember it actually.</p>
<p>The <code>ax1</code> and <code>ax2</code> objects, like <code>plt</code>, has
equivalent <code>set_title</code>, <code>set_xlabel</code> and
<code>set_ylabel</code> functions. Infact, the <code>plt.title()</code> actually
calls the current axes <code>set_title()</code> to do the job.</p>
<ul>
<li>plt.xlabel() → ax.set_xlabel()
</li><li>plt.ylabel() → ax.set_ylabel()
</li><li>plt.xlim() → ax.set_xlim()
</li><li>plt.ylim() → ax.set_ylim()
</li><li>plt.title() → ax.set_title()</li></ul>
<p>Alternately, to save keystrokes, you can set multiple things in one go using
the <code>ax.set()</code>.</p><pre><code class="python language-python">ax1.set(title='Scatterplot Greendots', xlabel='X', ylabel='Y', xlim=

(0,6), ylim=(0,12))
ax2.set(title='Scatterplot Bluestars', xlabel='X', ylabel='Y', xlim=(0,6), ylim=(0,12))
</code></pre>

<br>
<h2 id="#5.-Object-Oriented-Syntax-vs-Matlab-like-Syntax">5. Object Oriented Syntax vs Matlab like Syntax</h2>
<p>A known ‘problem’ with learning matplotlib is, it has two coding
interfaces:</p>
<ol>
<li>Matlab like syntax
</li><li>Object oriented syntax.</li></ol>
<p>This is partly the reason why matplotlib doesn’t have one consistent way of
achieving the same given output, making it a bit difficult to understand for new
comers.</p>
<p>The syntax you’ve seen so far is the Object-oriented syntax, which I
personally prefer and is more intuitive and pythonic to work with.</p>
<p>However, since the original purpose of matplotlib was to recreate the
plotting facilities of matlab in python, the matlab-like-syntax is retained and
still works.</p>
<p>The matlab syntax is <strong>‘stateful’.</strong></p>
<p>That means, the <code>plt</code> keeps track of what the current
<code>axes</code> is. So whatever you draw with <code>plt.{anything}</code> will
reflect only on the current subplot.</p>
<p>Practically speaking, the main difference between the two syntaxes is, in
matlab-like syntax, all plotting is done using <code>plt</code> methods instead
of the respective <code>axes</code>‘s method as in object oriented syntax.</p>
<p>So, how to recreate the above multi-subplots figure (or any other figure for
that matter) using matlab-like syntax?</p>
<p>The general procedure is: You manually create one subplot at a time (using
<code>plt.subplot()</code> or <code>plt.add_subplot()</code>) and immediately
call <code>plt.plot()</code> or <code>plt.{anything}</code> to modify that
specific subplot (axes). Whatever method you call using <code>plt</code> will be
drawn in the current <code>axes</code>.</p>
<p>The code below shows this in practice.</p><pre><code class="python language-python">plt.figure(figsize=(10,4), dpi=120) # 10 is width, 4 is

height

# Left hand side plot
plt.subplot(1,2,1)# (nRows, nColumns, axes number to plot)
plt.plot(, , 'go')# green dots
plt.title('Scatterplot Greendots')
plt.xlabel('X'); plt.ylabel('Y')
plt.xlim(0, 6); plt.ylim(0, 12)

# Right hand side plot
plt.subplot(1,2,2)
plt.plot(, , 'b*')# blue stars
plt.title('Scatterplot Bluestars')
plt.xlabel('X'); plt.ylabel('Y')
plt.xlim(0, 6); plt.ylim(0, 12)
plt.show()
</code></pre>
<img class="aligncenter size-shareaholic-thumbnail wp-image-1822" alt="Matplotlib double scatterplot"

src="https://tongyici.net:5556/static/data/math/matplotlib/07_Matplotlib_double_scatterplot_2-min.png">
<p>Let’s breakdown the above piece of code.</p>
<p>In <code>plt.subplot(1,2,1)</code>, the first two values, that is (1,2)
specifies the number of rows (1) and columns (2) and the third parameter (1)
specifies the position of current subplot. The subsequent <code>plt</code>
functions, will always draw on this current subplot.</p>
<p>You can get a reference to the current (subplot) axes with
<code>plt.gca()</code> and the current figure with <code>plt.gcf()</code>.
Likewise, <code>plt.cla()</code> and <code>plt.clf()</code> will clear the
current axes and figure respectively.</p>
<p>Alright, compare the above code with the object oriented (OO) version. The OO
version might look a but confusing because it has a mix of both <code>ax1</code>
and <code>plt</code> commands.</p>
<p>However, there is a significant advantage with <code>axes</code>
approach.</p>
<p>That is, since <code>plt.subplots</code> returns all the axes as separate
objects, you can avoid writing repetitive code by looping through the axes.</p>
<p>Always remember: <code>plt.plot()</code> or <code>plt.{anything}</code> will
always act on the plot in the current <code>axes</code>, whereas,
<code>ax.{anything}</code> will modify the plot inside that specific
<code>ax</code>.</p><pre><code class="python language-python"># Draw multiple plots using for-loops using object oriented syntax
import numpy as np
from numpy.random import seed, randint
seed(100)

# Create Figure and Subplots
fig, axes = plt.subplots(2,2, figsize=(10,6), sharex=True, sharey=True, dpi=120)

# Define the colors and markers to use
colors = {0:'g', 1:'b', 2:'r', 3:'y'}
markers = {0:'o', 1:'x', 2:'*', 3:'p'}

# Plot each axes
for i, ax in enumerate(axes.ravel()):
ax.plot(sorted(randint(0,10,10)), sorted(randint<br>(0,10,10)), marker=markers[(i)], color=colors[(i)])
ax.set_title('Ax: ' + str(i))
ax.yaxis.set_ticks_position('none')

plt.suptitle('Four Subplots in One Figure', verticalalignment='bottom', fontsize=16)   
plt.tight_layout()
plt.show()
</code></pre>
<img class="aligncenter size-shareaholic-thumbnail wp-image-1823" alt="Matplotlib subplots"

src="https://tongyici.net:5556/static/data/math/matplotlib/08_Matplotlib_subplots-min.png" >
<p>Did you notice in above plot, the Y-axis does not have ticks?</p>
<p>That’s because I used <code>ax.yaxis.set_ticks_position('none')</code> to
turn off the Y-axis ticks. This is another advantage of the object-oriented
interface. You can actually get a reference to any specific element of the plot
and use its methods to manipulate it.</p>
<p>Can you guess how to turn off the X-axis ticks?</p>
<p>The <code>plt.suptitle()</code> added a main title at figure level title.
<code>plt.title()</code> would have done the same for the current subplot
(axes).</p>
<p>The <code>verticalalignment='bottom'</code> parameter denotes the hingepoint
should be at the bottom of the title text, so that the main title is pushed
slightly upwards.</p>
<p>Alright, What you’ve learned so far is the core essence of how to create a
plot and manipulate it using matplotlib. Next, let’s see how to get the
reference to and modify the other components of the plot</p>

<br>
<h2 id="#6.-How-to-Modify-the-Axis-Ticks-Positions-and-Labels">6. How to Modify
the Axis Ticks Positions and Labels</h2>
<p>There are 3 basic things you will probably ever need in matplotlib when it
comes to manipulating axis ticks:<br>1. How to control the position and tick
labels? (using plt.xticks() or ax.set<em>xticks() and
ax.set</em>xticklabels())<br>2. How to control which axis’s ticks
(top/bottom/left/right) should be displayed (using plt.tick_params())<br>3.
Functional formatting of tick labels</p>
<p>If you are using <code>ax</code> syntax, you can use
<code>ax.set_xticks()</code> and <code>ax.set_xticklabels()</code> to set the
positions and label texts respectively. If you are using the <code>plt</code>
syntax, you can set both the positions as well as the label text in one call
using the <code>plt.xticks()</code>.</p>
<p>Actually, if you look at the code of <code>plt.xticks()</code> method (by
typing <code>??plt.xticks</code> in jupyter notebook), it calls
<code>ax.set_xticks()</code> and <code>ax.set_xticklabels()</code> to do the
job. <code>plt.xticks</code> takes the <code>ticks</code> and
<code>labels</code> as required parameters but you can also adjust the label’s
<code>fontsize</code>, <code>rotation</code>, ‘horizontalalignment’ and
‘verticalalignment’ of the hinge points on the labels, like I’ve done in the
below example.</p><pre><code class="python language-python">from matplotlib.ticker import FuncFormatter

def rad_to_degrees(x, pos):
    'converts radians to degrees'
    return round(x * 57.2985, 2)

plt.figure(figsize=(12,7), dpi=100)
X = np.linspace(0,2*np.pi,1000)
plt.plot(X,np.sin(X))
plt.plot(X,np.cos(X))

# 1. Adjust x axis Ticks
plt.xticks(ticks=np.arange(0, 440/57.2985, 90/57.2985), fontsize=12, rotation=30, ha='center', <br>va='top')# 1 radian = 57.2985 degrees

# 2. Tick Parameters
plt.tick_params(axis='both',bottom=True, top=True, left=True, right=True, direction='in', <br>which='major', grid_color='blue')

# 3. Format tick labels to convert radians to degrees
formatter = FuncFormatter(rad_to_degrees)
plt.gca().xaxis.set_major_formatter(formatter)

plt.grid(linestyle='--', linewidth=0.5, alpha=0.15)
plt.title('Sine and Cosine Waves\n(Notice the ticks are on all 4 sides pointing inwards, radians <br>converted to degrees in x axis)',

fontsize=14)
plt.show()
</code></pre>
<img class="aligncenter size-shareaholic-thumbnail wp-image-1824" alt="09 Modify Axis Ticks Positions Matplotlib"

src="https://tongyici.net:5556/static/data/math/matplotlib/09_Modify_Axis_Ticks_Positions_Matplotlib-min.png" >
<p>In above code, <code>plt.tick_params()</code> is used to determine which all
axis of the plot (‘top’ / ‘bottom’ / ‘left’ / ‘right’) you want to draw the
ticks and which direction (‘in’ / ‘out’) the tick should point to.</p>
<p>the <code>matplotlib.ticker</code> module provides the
<code>FuncFormatter</code> to determine how the final tick label should be
shown.</p>

<br>
<h2 id="#7.-Understanding-the-rcParams,-Colors-and-Plot-Styles">7. Understanding
the rcParams, Colors and Plot Styles</h2>
<p>The look and feel of various components of a matplotlib plot can be set
globally using <code>rcParams</code>. The complete list of <code>rcParams</code>
can be viewed by typing:</p><pre><code class="python language-python">mpl.rc_params()
# RcParams({'_internal.classic_mode': False,
#         'agg.path.chunksize': 0,
#         'animation.avconv_args': [],
#         'animation.avconv_path': 'avconv',
#         'animation.bitrate': -1,
#         'animation.codec': 'h264',
#         ... TRUNCATED LaRge OuTPut ...
</code></pre>
<p>You can adjust the params you’d like to change by updating it. The below
snippet adjusts the font by setting it to ‘stix’, which looks great on plots by
the way.</p><pre><code class="python language-python">mpl.rcParams.update({'font.size': 18, 'font.family': 'STIXGeneral', 'mathtext.fontset':

'stix'})
</code></pre>
<p>After modifying a plot, you can rollback the rcParams to default setting
using:</p><pre><code class="python language-python">mpl.rcParams.update(mpl.rcParamsDefault)# reset to defaults
</code></pre>
<p>Matplotlib comes with pre-built styles which you can look by typing:</p><pre><code class="python language-python">plt.style.available
# ['seaborn-dark', 'seaborn-darkgrid', 'seaborn-ticks', 'fivethirtyeight',
#'seaborn-whitegrid', 'classic', '_classic_test', 'fast', 'seaborn-talk',
#'seaborn-dark-palette', 'seaborn-bright', 'seaborn-pastel', 'grayscale',
#'seaborn-notebook', 'ggplot', 'seaborn-colorblind', 'seaborn-muted',
#'seaborn', 'Solarize_Light2', 'seaborn-paper', 'bmh', 'tableau-colorblind10',
#'seaborn-white', 'dark_background', 'seaborn-poster', 'seaborn-deep']
</code></pre><pre><code class="python language-python">import matplotlib as mpl
mpl.rcParams.update({'font.size': 18, 'font.family': 'STIXGeneral', 'mathtext.fontset': 'stix'})

def plot_sine_cosine_wave(style='ggplot'):
    plt.style.use(style)
    plt.figure(figsize=(7,4), dpi=80)
    X = np.linspace(0,2*np.pi,1000)
    plt.plot(X,np.sin(X)); plt.plot(X,np.cos(X))
    plt.xticks(ticks=np.arange(0, 440/57.2985, 90/57.2985),<br>labels = ['0','pi/2','pi','3*pi/2','2*pi']) # 1 radian = 57.2985 degrees
    plt.gca().set(ylim=(-1.25, 1.25), xlim=(-.5, 7))
    plt.title(style, fontsize=18)
    plt.show()

plot_sine_cosine_wave('seaborn-notebook')   
plot_sine_cosine_wave('ggplot')   
plot_sine_cosine_wave('bmh')   
</code></pre>
<img class="aligncenter size-medium wp-image-1825" alt="seaborn-notebook"

src="https://tongyici.net:5556/static/data/math/matplotlib/10_1_Matplotlib_Styles_seaborn-notebook-min.png" >
<img class="aligncenter size-medium wp-image-1826" alt="ggplot"

src="https://tongyici.net:5556/static/data/math/matplotlib/10_2_Matplotlib_Styles_ggplot-min.png" >
<img class="aligncenter size-medium wp-image-1827" alt="bmh"

src="https://tongyici.net:5556/static/data/math/matplotlib/10_3_Matplotlib_Styles_bmh-min.png" >
<p>I’ve just shown few of the pre-built styles, the rest of the list is
definitely worth a look.</p>
<p>Matplotlib also comes with pre-built colors and palettes. Type the following
in your jupyter/python console to check out the available colors.</p><pre><code class="python language-python"># View Colors
mpl.colors.CSS4_COLORS# 148 colors
mpl.colors.XKCD_COLORS# 949 colors
mpl.colors.BASE_COLORS# 8 colors
#&gt; {'b': (0, 0, 1),
#&gt;'g': (0, 0.5, 0),
#&gt;'r': (1, 0, 0),
#&gt;'c': (0, 0.75, 0.75),
#&gt;'m': (0.75, 0, 0.75),
#&gt;'y': (0.75, 0.75, 0),
#&gt;'k': (0, 0, 0),
#&gt;'w': (1, 1, 1)}
</code></pre><pre><code class="python language-python"># View first 10 Palettes
dir(plt.cm)[:10]
#&gt; ['Accent', 'Accent_r', 'Blues', 'Blues_r',
#&gt;'BrBG', 'BrBG_r', 'BuGn', 'BuGn_r', 'BuPu', 'BuPu_r']
</code></pre>
<img class="aligncenter size-shareaholic-thumbnail wp-image-1842" alt="Matplotlib Colors List"

src="https://tongyici.net:5556/static/data/math/matplotlib/matplotlib_colors-min.png" >

<br>
<h2 id="#8.-How-to-Customise-the-Legend">8. How to Customise the Legend</h2>
<p>The most common way to make a legend is to define the <code>label</code>
parameter for each of the plots and finally call <code>plt.legend()</code>.</p>
<p>However, sometimes you might want to construct the legend on your own. In
that case, you need to pass the plot items you want to draw the legend for and
the legend text as parameters to <code>plt.legend()</code> in the following
format:</p>
<p><code>plt.legend((line1, line2, line3), ('label1', 'label2',
'label3'))</code></p><pre><code class="python language-python"># plt.style.use('seaborn-notebook')
plt.figure(figsize=(10,7), dpi=80)
X = np.linspace(0, 2*np.pi, 1000)
sine = plt.plot(X,np.sin(X)); cosine = plt.plot(X,np.cos(X))
sine_2 = plt.plot(X,np.sin(X+.5)); cosine_2 = plt.plot(X,np.cos(X+.5))
plt.gca().set(ylim=(-1.25, 1.5), xlim=(-.5, 7))
plt.title('Custom Legend Example', fontsize=18)

# Modify legend
plt.legend(, cosine, sine_2, cosine_2],   # plot items
['sine curve','cosine curve',<br>'sine curve 2','cosine curve 2'],
frameon=True,          # legend border
framealpha=1,         # transparency of border
ncol=2,                     # num columns
shadow=True,            # shadow on
borderpad=1,            # thickness of border
title='Sines and Cosines')    # title
plt.show()
</code></pre>
<img class="aligncenter size-shareaholic-thumbnail wp-image-1829" alt="Customize Legend in Matplotlib"

src="https://tongyici.net:5556/static/data/math/matplotlib/11_Customize_Legend_Matplotlib-min.png" >

<br>
<h2 id="#9.-How-to-Add-Texts,-Arrows-and-Annotations">9. How to Add Texts, Arrows
and Annotations</h2>
<p><code>plt.text</code> and <code>plt.annotate</code> adds the texts and
annotations respectively. If you have to plot multiple texts you need to call
<code>plt.text()</code> as many times typically in a for-loop.</p>
<p>Let’s annotate the peaks and troughs adding <code>arrowprops</code> and a
<code>bbox</code> for the text.</p><pre><code class="python language-python"># Texts, Arrows and Annotations Example
# ref: https://matplotlib.org/users/annotations_guide.html
plt.figure(figsize=(14,7), dpi=120)
X = np.linspace(0, 8*np.pi, 1000)
sine = plt.plot(X,np.sin(X), color='tab:blue');

# 1. Annotate with Arrow Props and bbox
plt.annotate('Peaks', xy=(90/57.2985, 1.0), xytext=(90/57.2985, 1.5),
bbox=dict(boxstyle='square', fc='green', linewidth=0.1),
arrowprops=dict(facecolor='green', shrink=0.01, width=0.1),
fontsize=12, color='white', horizontalalignment='center')

# 2. Texts at Peaks and Troughs
for angle in :
    plt.text(angle/57.2985, 1.05, str(angle) + "\ndegrees", <br>transform=plt.gca().transData, horizontalalignment='center', color='green')

for angle in :
    plt.text(angle/57.2985, -1.3, str(angle) + "\ndegrees", <br>transform=plt.gca().transData, <br>horizontalalignment='center', color='red')   

plt.gca().set(ylim=(-2.0, 2.0), xlim=(-.5, 26))
plt.title('Annotations and Texts Example', fontsize=18)
plt.show()
</code></pre>
<img class="aligncenter size-shareaholic-thumbnail wp-image-1830" alt="Matplotlib Annotations"

src="https://tongyici.net:5556/static/data/math/matplotlib/12_Annotation_Texts_Matplotlib-min.png" >
<p>Notice, all the text we plotted above was in relation to the data.</p>
<p>That is, the x and y position in the <code>plt.text()</code> corresponds to
the values along the x and y axes. However, sometimes you might work with data
of different scales on different subplots and you want to write the texts in the
same position on all the subplots.</p>
<p>In such case, instead of manually computing the x and y positions for each
axes, you can specify the x and y values in relation to the axes (instead of x
and y axis values).</p>
<p>You can do this by setting <code>transform=ax.transData</code>.</p>
<p>The lower left corner of the axes has (x,y) = (0,0) and the top right corner
will correspond to (1,1).</p>
<p>The below plot shows the position of texts for the same values of (x,y) =
(0.50, 0.02) with respect to the Data(<code>transData</code>),
Axes(<code>transAxes</code>) and Figure(<code>transFigure</code>)
respectively.</p><pre><code class="python language-python"># Texts, Arrows and Annotations Example
plt.figure(figsize=(14,7), dpi=80)
X = np.linspace(0, 8*np.pi, 1000)

# Text Relative to DATA
plt.text(0.50, 0.02, "Text relative to the DATA centered at : (0.50, 0.02)", <br>transform=plt.gca().transData, fontsize=14, ha='center',

color='blue')

# Text Relative to AXES
plt.text(0.50, 0.02, "Text relative to the AXES centered at : (0.50, 0.02)", <br>transform=plt.gca().transAxes, fontsize=14, ha='center',

color='blue')

# Text Relative to FIGURE
plt.text(0.50, 0.02, "Text relative to the FIGURE centered at : (0.50, 0.02)", <br>transform=plt.gcf().transFigure, fontsize=14, ha='center',

color='blue')

plt.gca().set(ylim=(-2.0, 2.0), xlim=(0, 2))
plt.title('Placing Texts Relative to Data, Axes and Figure', fontsize=18)
plt.show()
</code></pre>
<img class="aligncenter size-shareaholic-thumbnail wp-image-1831" alt="Texts Relative to Data Axes Matplotlib"

src="https://tongyici.net:5556/static/data/math/matplotlib/13_Texts_Relative_to_Data_Axes_Matplotlib-min.png" >

<br>
<h2 id="#10.-How-to-customize-matplotlib's-subplots-layout">10. How to customize
matplotlib’s subplots layout</h2>
<p>Matplotlib provides two convenient ways to create customized multi-subplots
layout.</p>
<ul>
<li><code>plt.subplot2grid</code>
</li><li><code>plt.GridSpec</code></li></ul>
<p>Both <code>plt.subplot2grid</code> and <code>plt.GridSpec</code> lets you
draw complex layouts. Below is a nice <code>plt.subplot2grid</code> example.</p><pre><code class="python language-python"># Supplot2grid

approach
fig = plt.figure()
ax1 = plt.subplot2grid((3,3), (0,0), colspan=2, rowspan=2) # topleft
ax3 = plt.subplot2grid((3,3), (0,2), rowspan=3)            # right
ax4 = plt.subplot2grid((3,3), (2,0))                     # bottom left
ax5 = plt.subplot2grid((3,3), (2,1))                     # bottom right
fig.tight_layout()
</code></pre>
<img class="aligncenter size-shareaholic-thumbnail wp-image-1832" alt="Matplotlib Custom Layout with subplot2grid"

src="https://tongyici.net:5556/static/data/math/matplotlib/14_Layout_1_Matplotlib-min.png" >
<p>Using <code>plt.GridSpec</code>, you can use either a
<code>plt.subplot()</code> interface which takes part of the grid specified by
<code>plt.GridSpec(nrow, ncol)</code> or use the <code>ax =
fig.add_subplot(g)</code> where the <code>GridSpec</code> is defined by
<code>height_ratios</code> and <code>weight_ratios</code>.</p><pre><code class="python language-python"># GridSpec Approach 1
import matplotlib.gridspec as gridspec
fig = plt.figure()
grid = plt.GridSpec(2, 3)# 2 rows 3 cols
plt.subplot(grid)# top left
plt.subplot(grid)   # top right
plt.subplot(grid)# bottom left
plt.subplot(grid)# bottom right
fig.tight_layout()
</code></pre>
<img class="aligncenter size-medium wp-image-1833" alt="Matplotlib Custom Layout - Gridspec"

src="https://tongyici.net:5556/static/data/math/matplotlib/15_Layout_2_Matplotlib-min.png" ><pre><code class="python language-python"># GridSpec

Approach 2
import matplotlib.gridspec as gridspec
fig = plt.figure()
gs = gridspec.GridSpec(2, 2, height_ratios=, width_ratios=)
for g in gs:
    ax = fig.add_subplot(g)   
fig.tight_layout()
</code></pre>
<img class="aligncenter size-medium wp-image-1834" alt="Matplotlib Custom Layout"

src="https://tongyici.net:5556/static/data/math/matplotlib/16_Layout_3_Matplotlib-min.png" >
<p>The above examples showed layouts where the subplots dont overlap. It is
possible to make subplots to overlap. Infact you can draw an <code>axes</code>
inside a larger <code>axes</code> using <code>fig.add_axes()</code>. You need to
specify the x,y positions relative to the figure and also the width and height
of the inner plot.</p>
<p>Below is an example of an inner plot that zooms in to a larger plot.</p><pre><code class="python language-python"># Plot inside a plot
plt.style.use('seaborn-whitegrid')
fig, ax = plt.subplots(figsize=(10,6))
x = np.linspace(-0.50, 1., 1000)

# Outer Plot
ax.plot(x, x**2)
ax.plot(x, np.sin(x))
ax.set(xlim=(-0.5, 1.0), ylim=(-0.5,1.2))
fig.tight_layout()

# Inner Plot
inner_ax = fig.add_axes() # x, y, width, height
inner_ax.plot(x, x**2)
inner_ax.plot(x, np.sin(x))
inner_ax.set(title='Zoom In', xlim=(-.2, .2), ylim=(-.01, .02),
    yticks = [-0.01, 0, 0.01, 0.02], xticks=[-0.1,0,.1])
ax.set_title("Plot inside a Plot", fontsize=20)
plt.show()
mpl.rcParams.update(mpl.rcParamsDefault)# reset to defaults
</code></pre>
<img class="aligncenter size-shareaholic-thumbnail wp-image-1835" alt="Plot inside a plot"

src="https://tongyici.net:5556/static/data/math/matplotlib/17_Plot_inside_a_plot_Matplotlib-min.png" >

<br>
<h2 id="#11.-How-is-scatterplot-drawn-with-plt.plot-different-from-plt.scatter">11.
How is scatterplot drawn with plt.plot different from plt.scatter</h2>
<p>The difference is <code>plt.plot()</code> does not provide options to change
the color and size of point dynamically (based on another array). But
<code>plt.scatter()</code> allows you to do that.</p>
<p>By varying the size and color of points, you can create nice looking bubble
plots.</p>
<p>Another convenience is you can directly use a pandas dataframe to set the x
and y values, provided you specify the source dataframe in the <code>data</code>
argument.</p>
<p>You can also set the color <code>'c'</code> and size <code>'s'</code> of the
points from one of the dataframe columns itself.</p><pre><code class="python language-python"># Scatterplot with varying size and color of

points
import pandas as pd
midwest = pd.read_csv("https://raw.githubusercontent.com/selva86/datasets/master/midwest_filter.csv")

# Plot
fig = plt.figure(figsize=(14, 7), dpi= 80, facecolor='w', edgecolor='k')   
plt.scatter('area', 'poptotal', data=midwest, s='dot_size', c='popdensity', <br>cmap='Reds', edgecolors='black', linewidths=.5)
plt.title("Bubble Plot of PopTotal vs Area\n(color: 'popdensity' &amp; size: 'dot_size'<br> - both are numeric columns in midwest)",

fontsize=16)
plt.xlabel('Area', fontsize=18)
plt.ylabel('Poptotal', fontsize=18)
plt.colorbar()
plt.show()   
</code></pre>
<img class="aligncenter size-shareaholic-thumbnail wp-image-1836" alt="Bubble plot in Matplotlib - colorbar"

src="https://tongyici.net:5556/static/data/math/matplotlib/18_Bubbleplot_1_Matplotlib-min.png" ><pre><code class="python language-python">#

Import data
import pandas as pd
midwest = pd.read_csv("https://raw.githubusercontent.com/selva86/datasets/master/midwest_filter.csv")

# Plot
fig = plt.figure(figsize=(14, 9), dpi= 80, facecolor='w', edgecolor='k')   
colors = plt.cm.tab20.colors
categories = np.unique(midwest['category'])
for i, category in enumerate(categories):
    plt.scatter('area', 'poptotal', <br>data=midwest.loc, s='dot_size', <br>c=colors[(i)], label=str(category),

edgecolors='black', linewidths=.5)

# Legend for size of points
for dot_size in :
    plt.scatter([], [], c='k', alpha=0.5, s=dot_size, <br>label=str(dot_size) + ' TotalPop')
plt.legend(loc='upper right', scatterpoints=1, frameon=False, labelspacing=2, <br>title='Saravana Stores', fontsize=8)
plt.title("Bubble Plot of PopTotal vs Area\n(color: 'category' <br>- a categorical column in midwest)", fontsize=18)
plt.xlabel('Area', fontsize=16)
plt.ylabel('Poptotal', fontsize=16)
plt.show()   
</code></pre>
<img class="aligncenter size-shareaholic-thumbnail wp-image-1837" alt="Bubbleplot in Matplotlib"

src="https://tongyici.net:5556/static/data/math/matplotlib/19_Bubbleplot_2_Matplotlib-min.png" ><pre><code class="python language-python"># Save

the figure
plt.savefig("bubbleplot.png", transparent=True, dpi=120)
</code></pre>

<br>
<h2 id="#12.-How-to-draw-Histograms,-Boxplots-and-Time-Series">12. How to draw
Histograms, Boxplots and Time Series</h2>
<p>The methods to draw different types of plots are present in pyplot
(<code>plt</code>) as well as <code>Axes</code>. The below example shows basic
examples of few of the commonly used plot types.</p><pre><code class="python language-python">import pandas as pd

# Setup the subplot2grid Layout
fig = plt.figure(figsize=(10, 5))
ax1 = plt.subplot2grid((2,4), (0,0))
ax2 = plt.subplot2grid((2,4), (0,1))
ax3 = plt.subplot2grid((2,4), (0,2))
ax4 = plt.subplot2grid((2,4), (0,3))
ax5 = plt.subplot2grid((2,4), (1,0), colspan=2)
ax6 = plt.subplot2grid((2,4), (1,2))
ax7 = plt.subplot2grid((2,4), (1,3))

# Input Arrays
n = np.array()
x = np.linspace(0,5,10)
xx = np.linspace(-0.75, 1., 100)

# Scatterplot
ax1.scatter(xx, xx + np.random.randn(len(xx)))
ax1.set_title("Scatter Plot")

# Step Chart
ax2.step(n, n**2, lw=2)
ax2.set_title("Step Plot")

# Bar Chart
ax3.bar(n, n**2, align="center", width=0.5, alpha=0.5)
ax3.set_title("Bar Chart")

# Fill Between
ax4.fill_between(x, x**2, x**3, color="steelblue", alpha=0.5);
ax4.set_title("Fill Between");

# Time Series
dates = pd.date_range('2018-01-01', periods = len(xx))
ax5.plot(dates, xx + np.random.randn(len(xx)))
ax5.set_xticks(dates[::30])
ax5.set_xticklabels(dates.strftime('%Y-%m-%d')[::30])
ax5.set_title("Time Series")

# Box Plot
ax6.boxplot(np.random.randn(len(xx)))
ax6.set_title("Box Plot")

# Histogram
ax7.hist(xx + np.random.randn(len(xx)))
ax7.set_title("Histogram")

fig.tight_layout()
</code></pre>
<img class="aligncenter size-shareaholic-thumbnail wp-image-1838" alt="Histogram - Boxplot - Timeseries - Matplotlib"

src="https://tongyici.net:5556/static/data/math/matplotlib/20_Histogram_Boxplot_TimeSeries_Matplotlib-min.png">

<br>
<h2 id="whataboutmoreadvancedplots">What about more advanced plots?</h2>
<p>If you want to see more data analysis oriented examples of a particular plot
type, say histogram or time series, the <a href="https://www.machinelearningplus.com/plots/top-50-matplotlib-visualizations-the-master-plots-

python/">top
50 master plots for data analysis</a> will give you concrete examples of
presentation ready plots. This is a very useful tool to have, not only to
construct nice looking plots but to draw ideas to what type of plot you want to
make for your data.</p>

<br>
<h2 id="#13.-How-to-Plot-with-two-Y-Axis">13. How to Plot with two Y-Axis</h2>
<p>Plotting a line chart on the left-hand side axis is straightforward, which
you’ve already seen.</p>
<p>So how to draw the second line on the right-hand side y-axis?</p>
<p>The trick is to activate the right hand side Y axis using
<code>ax.twinx()</code> to create a second axes.</p>
<p>This second axes will have the Y-axis on the right activated and shares the
same x-axis as the original <code>ax</code>. Then, whatever you draw using this
second axes will be referenced to the secondary y-axis. The remaining job is to
just color the axis and tick labels to match the color of the lines.</p><pre><code class="python language-python"># Import Data
df = pd.read_csv("https://github.com/selva86/datasets/raw/master/economics.csv")
x = df['date']; y1 = df['psavert']; y2 = df['unemploy']

# Plot Line1 (Left Y Axis)
fig, ax1 = plt.subplots(1,1,figsize=(16,7), dpi= 80)
ax1.plot(x, y1, color='tab:red')

# Plot Line2 (Right Y Axis)
ax2 = ax1.twinx()# instantiate a second axes that shares the same x-axis
ax2.plot(x, y2, color='tab:blue')

# Just Decorations!! -------------------
# ax1 (left y axis)
ax1.set_xlabel('Year', fontsize=20)
ax1.set_ylabel('Personal Savings Rate', color='tab:red', fontsize=20)
ax1.tick_params(axis='y', rotation=0, labelcolor='tab:red' )

# ax2 (right Y axis)
ax2.set_ylabel("# Unemployed (1000's)", color='tab:blue', fontsize=20)
ax2.tick_params(axis='y', labelcolor='tab:blue')
ax2.set_title("Personal Savings Rate vs Unemployed: Plotting in Secondary Y Axis", fontsize=20)
ax2.set_xticks(np.arange(0, len(x), 60))
ax2.set_xticklabels(x[::60], rotation=90, fontdict={'fontsize':10})
plt.show()
</code></pre>
<img class="aligncenter size-shareaholic-thumbnail wp-image-1839" alt="Time Series in Secondary Axis"

src="https://tongyici.net:5556/static/data/math/matplotlib/21_Time_Series_in_Secondary_Axis_Matplotlib-min.png" >

<br>
<h2 id="#14.-Introduction-to-Seaborn">14. Introduction to Seaborn</h2>
<p>As the charts get more complex, the more the code you’ve got to write. For
example, in matplotlib, there is no direct method to draw a density plot of a
scatterplot with line of best fit. You get the idea.</p>
<p>So, what you can do instead is to use a higher level package like seaborn,
and use one of its prebuilt functions to draw the plot.</p>
<p>We are not going in-depth into seaborn. But let’s see how to get started and
where to find what you want. A lot of seaborn’s plots are suitable for data
analysis and the library works seamlessly with pandas dataframes.</p>
<p><code>seaborn</code> is typically imported as <code>sns</code>. Like
<code>matplotlib</code> it comes with its own set of pre-built styles and
palettes.</p><pre><code class="python language-python">import seaborn as sns
sns.set_style("white")

# Import Data
df = pd.read_csv("https://github.com/selva86/datasets/raw/master/mpg_ggplot2.csv")

# Draw Plot
plt.figure(figsize=(16,10), dpi= 80)
sns.kdeplot(df.loc == 4, "cty"], shade=True, color="g", label="Cyl=4", alpha=.7)
sns.kdeplot(df.loc == 6, "cty"], shade=True, color="dodgerblue", label="Cyl=6", alpha=.7)
sns.kdeplot(df.loc == 8, "cty"], shade=True, color="orange", label="Cyl=8", alpha=.7)

# Decoration
plt.title('Density Plot of City Mileage by n_Cylinders', fontsize=22)
plt.legend()
plt.show()
</code></pre>
<img class="aligncenter size-shareaholic-thumbnail wp-image-1840" alt="Density Plots in Matplotlib"

src="https://tongyici.net:5556/static/data/math/matplotlib/22_Density_Plot_Matplotlib-min.png"><pre><code class="python language-python"># Load

Dataset
df = sns.load_dataset('iris')

# Plot
plt.figure(figsize=(10,8), dpi= 80)
sns.pairplot(df, kind="reg", hue="species")
plt.show()
</code></pre><pre><code>&lt;Figure size 800x640 with 0 Axes&gt;
</code></pre>
<img class="aligncenter size-shareaholic-thumbnail wp-image-1841" alt="Pairplot - Seaborn"

src="https://tongyici.net:5556/static/data/math/matplotlib/23_Pairplot_Seaborn-min.png" >
<p>This is just to give a hint of what’s possible with seaborn. Maybe I will
write a separate post on it. However, the official seaborn <a href="https://seaborn.pydata.org/">page</a> has good examples for you to start
with.</p>

<br>
<h2 id="#15.-Conclusion">15. Conclusion</h2>
<p>Congratulations if you reached this far. Because we literally started from
scratch and covered the essential topics to making matplotlib plots.</p>
<p>We covered the syntax and overall structure of creating matplotlib plots, saw
how to modify various components of a plot, customized subplots layout, plots
styling, colors, palettes, draw different plot types etc.</p>
<p>If you want to get more practice, try taking up couple of plots listed in the
<a href="https://www.machinelearningplus.com/plots/top-50-matplotlib-visualizations-the-master-plots-python">top
50 plots</a> starting with correlation plots and try recreating it.</p>

<br>
<p>Until next time!</p>

</div>
页: [1]
查看完整版本: 【编程】学习Python绘图库Matplotlib