Question:
KeyError when plotting a sliced pandas dataframe with datetimes I get a KeyError when I try to plot a slice of a pandas DataFrame column with datetimes in it. Does anybody know what could cause this? I managed to reproduce the error in a little self contained example (which you can also view here: http://nbviewer.ipython.org/3714142/):
```
import numpy as np
from pandas import DataFrame
import datetime
from pylab import *

test = DataFrame({'x' : [datetime.datetime(2012,9,10) + datetime.timedelta(n) for n in range(10)],
                  'y' : range(10)})
```
Now if I plot:
```
plot(test['x'][0:5])
```
there is not problem, but when I plot:
```
plot(test['x'][5:10])
```
I get the KeyError below (and the error message is not very helpfull to me). This only happens with datetime columns, not with other columns (as far as I experienced). E.g. plot(test['y'][5:10]) is not a problem. Ther error message:
```
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-7-aa076e3fc4e0> in <module>()
----> 1 plot(test['x'][5:10])

C:\Python27\lib\site-packages\matplotlib\pyplot.pyc in plot(*args, **kwargs)
   2456         ax.hold(hold)
   2457     try:
-> 2458         ret = ax.plot(*args, **kwargs)
   2459         draw_if_interactive()
   2460     finally:

C:\Python27\lib\site-packages\matplotlib\axes.pyc in plot(self, *args, **kwargs)
   3846         lines = []
   3847
-> 3848         for line in self._get_lines(*args, **kwargs):
   3849             self.add_line(line)
   3850             lines.append(line)

C:\Python27\lib\site-packages\matplotlib\axes.pyc in _grab_next_args(self, *args, **kwargs)
    321                 return
    322             if len(remaining) <= 3:
--> 323                 for seg in self._plot_args(remaining, kwargs):
    324                     yield seg
    325                 return

C:\Python27\lib\site-packages\matplotlib\axes.pyc in _plot_args(self, tup, kwargs)
    298             x = np.arange(y.shape[0], dtype=float)
    299
--> 300         x, y = self._xy_from_xy(x, y)
    301
    302         if self.command == 'plot':

C:\Python27\lib\site-packages\matplotlib\axes.pyc in _xy_from_xy(self, x, y)
    215         if self.axes.xaxis is not None and self.axes.yaxis is not None:
    216             bx = self.axes.xaxis.update_units(x)
--> 217             by = self.axes.yaxis.update_units(y)
    218
    219             if self.command!='plot':

C:\Python27\lib\site-packages\matplotlib\axis.pyc in update_units(self, data)
   1277         neednew = self.converter!=converter
   1278         self.converter = converter
-> 1279         default = self.converter.default_units(data, self)
   1280         #print 'update units: default=%s, units=%s'%(default, self.units)
   1281         if default is not None and self.units is None:

C:\Python27\lib\site-packages\matplotlib\dates.pyc in default_units(x, axis)
   1153         'Return the tzinfo instance of *x* or of its first element, or None'
   1154         try:
-> 1155             x = x[0]
   1156         except (TypeError, IndexError):
   1157             pass

C:\Python27\lib\site-packages\pandas\core\series.pyc in __getitem__(self, key)
    374     def __getitem__(self, key):
    375         try:
--> 376             return self.index.get_value(self, key)
    377         except InvalidIndexError:
    378             pass

C:\Python27\lib\site-packages\pandas\core\index.pyc in get_value(self, series, key)
    529         """
    530         try:
--> 531             return self._engine.get_value(series, key)
    532         except KeyError, e1:
    533             if len(self) > 0 and self.inferred_type == 'integer':

C:\Python27\lib\site-packages\pandas\_engines.pyd in pandas._engines.IndexEngine.get_value (pandas\src\engines.c:1479)()

C:\Python27\lib\site-packages\pandas\_engines.pyd in pandas._engines.IndexEngine.get_value (pandas\src\engines.c:1374)()

C:\Python27\lib\site-packages\pandas\_engines.pyd in pandas._engines.DictIndexEngine.get_loc (pandas\src\engines.c:2498)()

C:\Python27\lib\site-packages\pandas\_engines.pyd in pandas._engines.DictIndexEngine.get_loc (pandas\src\engines.c:2460)()

KeyError: 0
```

Response:
HYRY explained why you get the KeyError. To plot with slices using matplotlib you can do:
```

```python
plot(test['x'][5:10].values)
#Output
#[<matplotlib.lines.Line2D at 0xc38348c>]
```

```python
plot(test['x'][5:10].reset_index(drop=True))
#Output
#[<matplotlib.lines.Line2D at 0xc37e3cc>]
#```
#x, y plotting in one go with 0.7.3
#```
```

```python
test[5:10].set_index('x')['y'].plot()
#Output
#<matplotlib.axes.AxesSubplot at 0xc48b1cc>
#```
```


Question:
Pandas missing x tick labels When I add c to a pandas plot, x tick labels disappear. Does anyone know how to add them back?
```
import pandas as pd

df = pd.DataFrame(
    {'mean': {0: 10,
              1: 16,
              2: 18,
              3: 22,
              4: 30},
     'size': {0: 103, 1: 2509, 2: 41939, 3: 145997, 4: 143530},
     'value': {0: 1.5, 1: 4.5, 2: 7.5, 3: 10.5, 4: 13.5}}
)

ax = df.plot(kind='scatter', x='value', y='mean', s=60, c='size', cmap='RdYlGn')
```
Tried to manually add x tick labels, but still not working.
```
ax.set_xticks(df['value'])
ax.set_xticklabels(df['value'])
```

Response:
Okay, I think this is a bug with pandas plot. However, this SO post shows the following workaround.
```
import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame(
    {'mean': {0: 10,
              1: 16,
              2: 18,
              3: 22,
              4: 30},
     'size': {0: 103, 1: 2509, 2: 41939, 3: 145997, 4: 143530},
     'value': {0: 1.5, 1: 4.5, 2: 7.5, 3: 10.5, 4: 13.5}}
)
fig, ax = plt.subplots()
df.plot(kind='scatter', x='value', y='mean', s=60, c='size', cmap='RdYlGn', ax=ax)
```


Question:
axis limits for scatter plot not holding in matplotlib I am trying to overlay a scatter plot onto a contour plot using matplotlib, which contains
```
plt.contourf(X, Y, XYprof.T, self.nLevels, extent=extentYPY, \
                 origin = 'lower')
    if self.doScatter == True and len(xyScatter['y']) != 0:
        plt.scatter(xyScatter['x'], xyScatter['y'], \
                    s=dSize, c=myColor, marker='.', edgecolor='none')
    plt.xlim(-xLimHist,  xLimHist)
    plt.ylim(-yLimHist, yLimHist)
    plt.xlabel(r'$x$')
    plt.ylabel(r'$y$')
```
What ends up happening is the resulting plots extend to include all of the scatter points, which can exceed the limits for the contour plot. Is there any way to get around this?

Response:
I used the following example to try and replicate your problem. If left to default, the range for x and y was -3 to 3. I input the xlim and ylim so the range for both was -2 to 2. It worked.
```
import numpy as np
   import matplotlib.pyplot as plt
   from pylab import *

   # the random data
   x = np.random.randn(1000)
   y = np.random.randn(1000)

   fig = plt.figure(1, figsize=(5.5,5.5))

   X, Y = meshgrid(x, y)
   Z1 = bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
   Z2 = bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
   Z = 10 * (Z1 - Z2)

   origin = 'lower'
   CS = contourf(x, y, Z, 10, # [-1, -0.1, 0, 0.1],
                 cmap=cm.bone,
                 origin=origin)

   title('Nonsense')
   xlabel('x-stuff')
   ylabel('y-stuff')

   # the scatter plot:
   axScatter = plt.subplot(111)
   axScatter.scatter(x, y)

   # set axes range
   plt.xlim(-2, 2)
   plt.ylim(-2, 2)

   show()
```


Question:
How to plot a rectangle on a datetime axis using matplotlib? I tried to plot a rectangle on a graph with a datetime x-axis using the following code:
```
from datetime import datetime, timedelta
from matplotlib.patches import Rectangle
import matplotlib.pyplot as plt

# Create new plot
fig = plt.figure()
ax = fig.add_subplot(111)

# Create rectangle
startTime = datetime.now()
width = timedelta(seconds = 1)
endTime = startTime + width
rect = Rectangle((startTime, 0), width, 1, color='yellow')

# Plot rectangle
ax.add_patch(rect)   ### ERROR HERE!!! ###
plt.xlim([startTime, endTime])
plt.ylim([0, 1])
plt.show()
```
However, I get the error:
```
TypeError: unsupported operand type(s) for +: 'float' and 'datetime.timedelta'
```
What's going wrong? (I'm using matplotlib version 1.0.1)

Response:
The problem is that matplotlib uses its own representation of dates/times (floating number of days), so you have to convert them first. Furthermore, you will have to tell the xaxis that it should have date/time ticks and labels. The code below does that:
```
from datetime import datetime, timedelta
from matplotlib.patches import Rectangle
import matplotlib.pyplot as plt
import matplotlib.dates as mdates

# Create new plot
fig = plt.figure()
ax = fig.add_subplot(111)

# Create rectangle x coordinates
startTime = datetime.now()
endTime = startTime + timedelta(seconds = 1)

# convert to matplotlib date representation
start = mdates.date2num(startTime)
end = mdates.date2num(endTime)
width = end - start

# Plot rectangle
rect = Rectangle((start, 0), width, 1, color='yellow')
ax.add_patch(rect)

# assign date locator / formatter to the x-axis to get proper labels
locator = mdates.AutoDateLocator(minticks=3)
formatter = mdates.AutoDateFormatter(locator)
ax.xaxis.set_major_locator(locator)
ax.xaxis.set_major_formatter(formatter)

# set the limits
plt.xlim([start-width, end+width])
plt.ylim([-.5, 1.5])

# go
plt.show()
```
Result: NOTE: Matplotlib 1.0.1 is very old. I can't guarantee that my example will work. You should try to update!


Question: Are there really only 4 Matplotlib Line Styles? I've been looking for new line styles in matplotlib, and the only line styles available are ["-", "--", "-.", ":",]. (The style options ['', ' ', 'None',] don't count because they just hide the lines.) Are there really only 4 line styles in Matplotlib pyplot? Are there any extensions that add further line styles? Is there a way to customise line styles? How about some three character line styles like: '--.': dash dash dot '-..': dash dot dot '...': dot dot dot (space) 'xxx': x's in a line '\/': Zig zags ie '\/\/\/\/' '::': parrallel dots, ie ::::: These are just some ideas to expand the range of line styles.

Response:
You can use the dashes kwarg to set custom dash styles. From the docs: Set the dash sequence, sequence of dashes with on off ink in points. If seq is empty or if seq = (None, None), the linestyle will be set to solid. Here's some examples based on a few of your suggestions. Obviously there are many more ways you could customise this.
```
import matplotlib.pyplot as plt

fig,ax = plt.subplots(1)

# 3 dots then space
ax.plot(range(10), range(10),     dashes=[3,6,3,6,3,18],  lw=3,c='b')

# dash dash dot
ax.plot(range(10), range(0,20,2), dashes=[12,6,12,6,3,6], lw=3,c='r')

# dash dot dot
ax.plot(range(10), range(0,30,3), dashes=[12,6,3,6,3,6],  lw=3,c='g')
```


Question:
Scale plot size of Matplotlib Plots in Jupyter Notebooks Is there a possibility to scale the plot size of matplotlib plots in jupyter notebooks? You could increase the plot size by changing the default values of figure.figsize, but this does not affect parameters like fontsize, linewidth, markersize etc. What I need is a plot where all the parameters are scaled accordingly. P.S.: To display plots in jupyter notebooks I use %matplotlib inline, see screenshot below. Edit For completeness, here is a code snippet doing exactly what I needed:
```
def scale_plot_size(factor=1.5):
    import matplotlib as mpl
    default_dpi = mpl.rcParamsDefault['figure.dpi']
    mpl.rcParams['figure.dpi'] = default_dpi*factor
```

Response:
You don't want to change the figure size. You want to change the dpi (dots per inch). Also see Relationship between dpi and figure size.
```
import matplotlib.pyplot as plt
%matplotlib inline

def plot(dpi):
    fig, ax=plt.subplots(dpi=dpi)
    ax.plot([2,4,1,5], label="Label")
    ax.legend()

for i in range(1,4):
    plot(i*72)
```


Question: How boxen plot is different from box plot? I want to know why there is boxen plot when we have box plot in sea-born library. I know one thing that boxen plot optimised way to represent data especially for large data-sets but i don't know why and other then this i don't have any good reasons to use boxen plot.

Response:
The box plot shows the median as the centerline (50th percentile), then the 25th and 75th percentile as the box boundaries. Then the IQR method is used to calculate outlier boundaries (1.5 * IQR + Q3 for the upper boundary, for example). Q3 is the 3rd quartile, or 75th percentile of the data (75% of the data is below this value). Outliers outside of the outlier whiskers are shown as distinct points. Boxenplots (actually called letter-value plots in the original paper and in the lvplot R package; that's lv as in letter-value) show the distribution differently and are better for bigger datasets. Classic boxplots can have too many outliers and don't show as much information about the distribution. Letter-value plots (boxenplots) start with the median (Q2, 50th percentile) as the centerline. Each successive level outward contains half of the remaining data. So the first two sections out from the centerline contain 50% of the data. After that, the next two sections contain 25% of the data. This continues until we are at the outlier level. Each level out is shaded lighter. There are 4 methods for calculating outliers (described in the paper and available in seaborn). The default is to end up with around 5-8 outliers in each tail. I illustrated with Diziet's nice figure: The original paper (from authors including Hadley Wickham) is linked in the seaborn boxenplot docs. Formula The amount of data outside each level is outside = 2^(-l), where l = 1, 2, 3..., and amount of data inside each level is inside = 1-outside. For first few levels rounded to 3 significant digits:
```
l   inside  outside
-------------------
1    50.0%    50.0%
2    75.0%    25.0%
3    87.5%    12.5%
4   93.75%    6.25%
5  96.875%   3.125%
6  98.438%   1.562%
7  99.219%   0.781%
8  99.609%   0.391%
9  99.805%   0.195%
```


Question:
How to change size of plot in xgboost.plot_importance?
```
xgboost.plot_importance(model, importance_type='gain')
```
I am not able to change size of this plot. I want to save this figure with proper size so that I can use it in pdf. I want similar like figize

Response:
It looks like plot_importance return an Axes object
```
ax = xgboost.plot_importance(...)
fig = ax.figure
fig.set_size_inches(h, w)
```
It also looks like you can pass an axes in
```
fig, ax = plt.subplots(figsize=(h, w))
xgboost.plot_importance(..., ax=ax)
```


Question:
How to plot collections.Counter histogram using matplotlib? How to plot histogram of following Counter object?:
```
w = collections.Counter()
l = ['a', 'b', 'b', 'b', 'c']
for o in l:
    w[o]+=1
```

Response:
Looking at your data and attempt, I guess you want a bar plot instead of a histogram. Histogram is used to plot a distribution but that is not what you have. You can simply use the keys and values as the arguments of plt.bar. This way, the keys will be automatically taken as the x-axis tick-labels.
```
import collections
import matplotlib.pyplot as plt
l = ['a', 'b', 'b', 'b', 'c']
w = collections.Counter(l)
plt.bar(w.keys(), w.values())
```


Question:
Seaborn lineplot high cpu; very slow compared to matplotlib I have the following dataframe.
```

```python
dfFinal
#Output
#module                                            vectime                                           vecvalue
#1906  client1.tcp  [1.1007512, 1.1015024, 1.1022536, 1.1030048, 1...  [0.0007512, 0.0007512, 0.0007512, 0.0007512, 0...
#1912  client2.tcp  [1.10079784, 1.10159568, 1.10239352, 1.1031913...  [0.00079784, 0.00079784, 0.00079784, 0.0007978...
#1918  client3.tcp  [1.10084448, 1.10168896, 1.10258008, 1.1036111...  [0.00084448, 0.00084448, 0.00089112, 0.0010310...
#```
#I want to plot the timeSeries vecvalue vs vectime for each module. The result is the following: To do so I can do as follows: 1) Matplotlib
#```
#start = datetime.datetime.now()
#
#for row in dfFinal.itertuples():
#    t = row.vectime
#    x = row.vecvalue
#    x = runningAvg(x)
#    plot(t,x)
#
#total = (datetime.datetime.now() - start).total_seconds()
#print("Total time: ",total)
#```
#Doing so, takes 0.07005 seconds to accomplish. 2) Seaborn
#```
#start = datetime.datetime.now()
#
#for row in dfFinal.itertuples():
#    t = row.vectime
#    x = row.vecvalue
#    x = runningAvg(x)
#    DF = pd.DataFrame({'x':x, 't':t})
#    sns.lineplot(x='t', y='x', data=DF)
#
#total = (datetime.datetime.now() - start).total_seconds()
#print("Total time: ",total)
#```
#Doing so, takes 19.157463 seconds to accomplish. Why is there such a huge difference? What is it that I'm doing so wrong that it takes that long to process a rather small DF?
```

Response: Set ci=None in the call to lineplot; otherwise, confidence intervals will be computed resulting in some expensive (and unnecessary) df.groupby calls. An aside: the snakeviz module is a great tool for quickly finding computational bottlenecks.


Question:
Matplotlib: Color-coded text in legend instead of a line On certain LCD monitors, the color of the horizontal lines in the legend is hard to tell apart. (See the image attached). So instead of drawing a line in the legend, is it possible to just color code the text itself? so another words, have "y=0x" in blue, "y=1x" in green, etc...
```
import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    ax.plot(x, i * x, label='$y = %ix$' % i)

ax.legend()

plt.show()
```
PS. if the line could be made thicker just in the legend, but not in the plot, this would also work.

Response:
I was wondering the same thing. Here is what I came up with to change the color of the font in the legend. I am not totally happy with this method, since it seems a little clumsy, but it seems to get the job done [Edit: see below for a better way]:
```
import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

colors = []
for i in xrange(5):
    line, = ax.plot(x, i * x, label='$y = %ix$' % i)
    colors.append(plt.getp(line,'color'))

leg = ax.legend()

for color,text in zip(colors,leg.get_texts()):
    text.set_color(color)

plt.show()
```
2016 Edit: Actually, there is a better way. You can simply iterate over the lines in the legend, which avoids needing to keep track of the colors as the lines are plotted. Much less clunky. Now, changing the line colors is basically a one-liner (okay, it's actually a two-liner). Here is the complete example:
```
import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

fig = plt.figure()
ax = plt.subplot(111)

for i in xrange(5):
    ax.plot(x, i*x, label='$y = %ix$'%i)

leg = ax.legend()

# change the font colors to match the line colors:
for line,text in zip(leg.get_lines(), leg.get_texts()):
    text.set_color(line.get_color())

plt.show()
```
2017 Edit: Lastly, if you really do want the color-coded text instead of a line (as the title suggests), then you can suppress the lines in the legend by using
```
leg = ax.legend(handlelength=0)
```


Question: Histogram with Boxplot above in Python Hi I wanted to draw a histogram with a boxplot appearing the top of the histogram showing the Q1,Q2 and Q3 as well as the outliers. Example phone is below. (I am using Python and Pandas) I have checked several examples using matplotlib.pyplot but hardly came out with a good example. And I also wanted to have the histogram curve appearing like in the image below. I also tried seaborn and it provided me the shape line along with the histogram but didnt find a way to incorporate with boxpot above it. can anyone help me with this to have this on matplotlib.pyplot or using pyplot

Response:
```
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

sns.set(style="ticks")

x = np.random.randn(100)

f, (ax_box, ax_hist) = plt.subplots(2, sharex=True,
                                    gridspec_kw={"height_ratios": (.15, .85)})

sns.boxplot(x, ax=ax_box)
sns.distplot(x, ax=ax_hist)

ax_box.set(yticks=[])
sns.despine(ax=ax_hist)
sns.despine(ax=ax_box, left=True)
```
From seaborn v0.11.2, sns.distplot is deprecated. Use sns.histplot for axes-level plots instead.
```py
np.random.seed(2022)
x = np.random.randn(100)

f, (ax_box, ax_hist) = plt.subplots(2, sharex=True, gridspec_kw={"height_ratios": (.15, .85)})

sns.boxplot(x=x, ax=ax_box)
sns.histplot(x=x, bins=12, kde=True, stat='density', ax=ax_hist)

ax_box.set(yticks=[])
sns.despine(ax=ax_hist)
sns.despine(ax=ax_box, left=True)
```


Question:
How can I pass parameters to on_key in fig.canvas.mpl_connect('key_press_event', on_key)? I have a function
```
def on_key(event):
```
Which I call from
```
fig.canvas.mpl_connect('key_press_event', on_key)
```
I would like to pass the parameters plt1, plt2, plt3 to on_key... how can I do this?

Response:
Probably
```
def on_key(event, arg1, arg2, arg3):
```
and
```
fig.canvas.mpl_connect('key_press_event', lambda event: on_key(event, plt1, plt2, plt3))
```
or as list
```
def on_key(event, args_list):
```
and
```
fig.canvas.mpl_connect('key_press_event', lambda event: on_key(event, [plt1, plt2, plt3]))
```


Question:
Plotting Ellipsoid with Matplotlib Does anyone have sample code for plotting ellipsoids? There is one for sphere on matplotlib site, but nothing for ellipsoids. I am trying to plot
```
x**2 + 2*y**2 + 2*z**2 = c
```
where c is a constant (like 10) that defines an ellipsoid. I tried the meshgrid(x,y) route, reworked the equation so z is on one side, but the sqrt is a problem. The matplotlib sphere example works with angles, u,v, but I am not sure how to work that for ellipsoid.

Response:
Here is how you can do it via spherical coordinates:
```
# from mpl_toolkits.mplot3d import Axes3D  # Not needed with Matplotlib 3.6.3
import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure(figsize=plt.figaspect(1))  # Square figure
ax = fig.add_subplot(111, projection='3d')

coefs = (1, 2, 2)  # Coefficients in a0/c x**2 + a1/c y**2 + a2/c z**2 = 1
# Radii corresponding to the coefficients:
rx, ry, rz = 1/np.sqrt(coefs)

# Set of all spherical angles:
u = np.linspace(0, 2 * np.pi, 100)
v = np.linspace(0, np.pi, 100)

# Cartesian coordinates that correspond to the spherical angles:
# (this is the equation of an ellipsoid):
x = rx * np.outer(np.cos(u), np.sin(v))
y = ry * np.outer(np.sin(u), np.sin(v))
z = rz * np.outer(np.ones_like(u), np.cos(v))

# Plot:
ax.plot_surface(x, y, z,  rstride=4, cstride=4, color='b')

# Adjustment of the axes, so that they all have the same span:
max_radius = max(rx, ry, rz)
for axis in 'xyz':
    getattr(ax, 'set_{}lim'.format(axis))((-max_radius, max_radius))

plt.show()
```
The resulting plot is similar to The program above actually produces a nicer looking "square" graphics. This solution is strongly inspired from the example in Matplotlib's gallery.


Question: Calling pylab.savefig without display in ipython I need to create a figure in a file without displaying it within IPython notebook. I am not clear on the interaction between IPython and matplotlib.pylab in this regard. But, when I call pylab.savefig("test.png") the current figure get's displayed in addition to being saved in test.png. When automating the creation of a large set of plot files, this is often undesirable. Or in the situation that an intermediate file for external processing by another app is desired. Not sure if this is a matplotlib or IPython notebook question.

Response:
This is a matplotlib question, and you can get around this by using a backend that doesn't display to the user, e.g. 'Agg':
```
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt

plt.plot([1,2,3])
plt.savefig('/tmp/test.png')
```
EDIT: If you don't want to lose the ability to display plots, turn off Interactive Mode, and only call plt.show() when you are ready to display the plots:
```
import matplotlib.pyplot as plt

# Turn interactive plotting off
plt.ioff()

# Create a new figure, plot into it, then close it so it never gets displayed
fig = plt.figure()
plt.plot([1,2,3])
plt.savefig('/tmp/test0.png')
plt.close(fig)

# Create a new figure, plot into it, then don't close it so it does get displayed
plt.figure()
plt.plot([1,3,2])
plt.savefig('/tmp/test1.png')

# Display all "open" (non-closed) figures
plt.show()
```


Question:
What is the necessity of plt.figure() in matplotlib?
```
plt.figure(figsize=(10,8))

plt.scatter(df['attacker_size'][df['year'] == 298],
        # attacker size in year 298 as the y axis
        df['defender_size'][df['year'] == 298],
        # the marker as
        marker='x',
        # the color
        color='b',
        # the alpha
        alpha=0.7,
        # with size
        s = 124,
        # labelled this
        label='Year 298')
```
In the above snippet of code collected from Scatterplot in Matplotlib, what is the necessity of plt.figure()? link above ais dead , self sustaining example :
```
import matplotlib.pyplot as plt

import pandas as pd

data = {
  "attacker_size": [420, 380, 390],
  "defender_size": [50, 40, 45]
}

df = pd.DataFrame(data, index = ["day1", "day2", "day3"])

print(df)

plt.figure(figsize=(10,8))

plt.scatter(df['attacker_size'],
        # attacker size in year 298 as the y axis
        df['defender_size'],
        # the marker as
        marker='x',
        # the color
        color='b',
        # the alpha
        alpha=0.7,
        # width size
        s = 150,
        # labelled this
        label='Test')
```

Response:
The purpose of using plt.figure() is to create a figure object. The whole figure is regarded as the figure object. It is necessary to explicitly use plt.figure() when we want to tweak the size of the figure and when we want to add multiple Axes objects in a single figure.
```
# in order to modify the size
fig = plt.figure(figsize=(12,8))
# adding multiple Axes objects
fig, ax_lst = plt.subplots(2, 2)  # a figure with a 2x2 grid of Axes
```
Parts of a Figure


Question:
Change xticklabels fontsize of seaborn heatmap Here is my question: I plot 7 variable's coefficient using sns.clustermap() x/y tickslabel seems really small(In my case, s1,s2,... s9) My attempt label='big ==> no effect plt.tick_params(axis='both', which='minor', labelsize=12) ===> cbar label has changed, but the x/y axes looks the same. Add My code:
```
ds =  pd.read_csv("xxxx.csv")
 corr = ds.corr().mul(100).astype(int)

 cmap = sns.diverging_palette(h_neg=210, h_pos=350, s=90, l=30, as_cmap=True)

 sns.clustermap(data=corr_s, annot=True, fmt='d',cmap = "Blues",annot_kws={"size": 16},)
```

Response:
Consider calling sns.set(font_scale=1.4) before plotting your data. This will scale all fonts in your legend and on the axes. My plot went from this, To this, Of course, adjust the scaling to whatever you feel is a good setting. Code:
```
sns.set(font_scale=1.4)
cmap = sns.diverging_palette(h_neg=210, h_pos=350, s=90, l=30, as_cmap=True)
sns.clustermap(data=corr, annot=True, fmt='d', cmap="Blues", annot_kws={"size": 16})
```


Question: Invert image displayed by imshow in matplotlib I wanted the imshow() function in matplotlib.pyplot to display images the opposite way, i.e upside down. Is there a simple way to do this?

Response: Specify the keyword argument origin='lower' or origin='upper' in your call to imshow.


Question:
plot multiple pandas dataframes in one graph I have created 6 different dataframes that eliminate the outliers of their own original data frames. Now, I'm trying to plot all of the dataframes that eliminate the outliers on the same graph. This is my code that eliminates the outliers in each data frame:
```
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.style.use("ggplot")

#---Original DataFrame
x = (g[0].time[:27236])
y = (g[0].data.f[:27236])
df = pd.DataFrame({'Time': x, 'Data': y})

#----Removes the outliers in a given DataFrame and plots a graph
newdf = df.copy()
newdf = df[~df.groupby('Data').transform( lambda x: abs(x-x.mean()) > 1.96*x.std()).values]
#newdf.plot('Time', 'Data')

#---Original DataFrame
x = (q[0].time[:47374])
y = (q[0].data.f[:47374])
df = pd.DataFrame({'Time': x, 'Data': y})

#----Removes the outliers in a given DataFrame and plots a graph
newdf = df.copy()
newdf2 = df[~df.groupby('Data').transform( lambda x: abs(x-x.mean()) > 1.96*x.std()).values]
#newdf2.plot('Time', 'Data')

#---Original DataFrame
x = (w[0].time[:25504])
y = (w[0].data.f[:25504])
df = pd.DataFrame({'Time': x, 'Data': y})

#----Removes the outliers in a given DataFrame and plots a graph
newdf = df.copy()
newdf3 = df[~df.groupby('Data').transform( lambda x: abs(x-x.mean()) > 1.96*x.std()).values]
#newdf3.plot('Time', 'Data')

#---Original DataFrame
x = (e[0].time[:47172])
y = (e[0].data.f[:47172])
df = pd.DataFrame({'Time': x, 'Data': y})

#----Removes the outliers in a given DataFrame and plots a graph
newdf = df.copy()
newdf4 = df[~df.groupby('Data').transform( lambda x: abs(x-x.mean()) > 1.96*x.std()).values]
#newdf4.plot('Time', 'Data')

#---Original DataFrame
x = (r[0].time[:21317])
y = (r[0].data.f[:21317])
df = pd.DataFrame({'Time': x, 'Data': y})

#----Removes the outliers in a given DataFrame and plots a graph
newdf = df.copy()
newdf5 = df[~df.groupby('Data').transform( lambda x: abs(x-x.mean()) > 1.96*x.std()).values]
#newdf5.plot('Time', 'Data')

#---Original DataFrame
x = (t[0].time[:47211])
y = (t[0].data.f[:47211])
df = pd.DataFrame({'Time': x, 'Data': y})

#----Removes the outliers in a given DataFrame and plots a graph
newdf = df.copy()
newdf6 = df[~df.groupby('Data').transform( lambda x: abs(x-x.mean()) > 1.96*x.std()).values]
#newdf6.plot('Time', 'Data')
```
If I remove the comment newdf.plot() I will be able to plot all of the graphs separately but I want them all on one graph. And yes, I've already read over http://matplotlib.org/examples/pylab_examples/subplots_demo.html but that link doesn't have any examples with multiple plots in one chart. I have also read this: http://pandas-docs.github.io/pandas-docs-travis/visualization.html which has some really great information but the examples that have multiple plots in one graph use the same data frame. I have 6 separate dataframes. I've thought of one solution to my problem would be to write all of the dataframes to the same excel file then plot them from excel, but that seems excessive and I don't need this data to be saved to an excel file. My question is this: How can I plot multiple pandas dataframes in the same graph. My graph after following Scott's advice What the graph should more or less look like

Response:
You need to use the ax parameter in pandas.dataframe.plot. Use on the first df.plot to grab a handle on that axes:
```
ax = newdf.plot()
```
then on subsequent plots use the ax parameter.
```
newdf2.plot(ax=ax)
...
newdf5.plot(ax=ax)
```


Question:
In matplotlib, how do you draw R-style axis ticks that point outward from the axes? Because they are drawn inside the plot area, axis ticks are obscured by the data in many matplotlib plots. A better approach is to draw the ticks extending from the axes outward, as is the default in ggplot, R's plotting system. In theory, this can be done by redrawing the tick lines with the TICKDOWN and TICKLEFT line-styles for the x-axis and y-axis ticks respectively:
```py
import matplotlib.pyplot as plt
import matplotlib.ticker as mplticker
import matplotlib.lines as mpllines

# Create everything, plot some data stored in `x` and `y`
fig = plt.figure()
ax = fig.gca()
plt.plot(x, y)

# Set position and labels of major and minor ticks on the y-axis
# Ignore the details: the point is that there are both major and minor ticks
ax.yaxis.set_major_locator(mplticker.MultipleLocator(1.0))
ax.yaxis.set_minor_locator(mplticker.MultipleLocator(0.5))

ax.xaxis.set_major_locator(mplticker.MultipleLocator(1.0))
ax.xaxis.set_minor_locator(mplticker.MultipleLocator(0.5))

# Try to set the tick markers to extend outward from the axes, R-style
for line in ax.get_xticklines():
    line.set_marker(mpllines.TICKDOWN)

for line in ax.get_yticklines():
    line.set_marker(mpllines.TICKLEFT)

# In real life, we would now move the tick labels farther from the axes so our
# outward-facing ticks don't cover them up

plt.show()
```
But in practice, that's only half the solution because the get_xticklines and get_yticklines methods return only the major tick lines. The minor ticks remain pointing inward. What's the work-around for the minor ticks?

Response:
In your matplotlib config file, matplotlibrc, you can set:
```
xtick.direction      : out     # direction: in or out
ytick.direction      : out     # direction: in or out
```
and this will draw both the major and minor ticks outward by default, like R. For a single program, simply do:
```
>> from matplotlib import rcParams
>> rcParams['xtick.direction'] = 'out'
>> rcParams['ytick.direction'] = 'out'
```


Question:
How can I remove the top and right axis? Instead of the default "boxed" axis style I want to have only the left and bottom axis, i.e.:
```
+------+         |
|      |         |
|      |   --->  |
|      |         |
+------+         +-------
```
This should be easy, but I can't find the necessary options in the docs.

Response:
This is the suggested Matplotlib 3 solution from the official website HERE:
```
import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x)

ax = plt.subplot(111)
ax.plot(x, y)

# Hide the right and top spines
ax.spines[['right', 'top']].set_visible(False)

plt.show()
```


Question:
Add x and y labels to a pandas plot Suppose I have the following code that plots something very simple using pandas:
```
import pandas as pd
values = [[1, 2], [2, 5]]
df2 = pd.DataFrame(values, columns=['Type A', 'Type B'],
                   index=['Index 1', 'Index 2'])
df2.plot(lw=2, colormap='jet', marker='.', markersize=10,
         title='Video streaming dropout by category')
```
How do I easily set x and y-labels while preserving my ability to use specific colormaps? I noticed that the plot() wrapper for pandas DataFrames doesn't take any parameters specific for that.

Response:
The df.plot() function returns a matplotlib.axes.AxesSubplot object. You can set the labels on that object.
```
ax = df2.plot(lw=2, colormap='jet', marker='.', markersize=10, title='Video streaming dropout by category')
ax.set_xlabel("x label")
ax.set_ylabel("y label")
```
Or, more succinctly: ax.set(xlabel="x label", ylabel="y label"). Alternatively, the index x-axis label is automatically set to the Index name, if it has one. so df2.index.name = 'x label' would work too.


Question:
changing default x range in histogram matplotlib I would like to change the default x range for the histogram plot. The range of the data is from 7 to 12. However, by default the histogram starts right at 7 and ends at 13. I want it to start at 6.5 and end at 12.5. However, the ticks should go from 7 to 12.How do I do it?
```
import asciitable
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab
import pylab
from pylab import xticks

data = asciitable.read(file)
hmag = data['col8']
visits = data['col14']
origin = data['col13']

n, bins, patches = plt.hist(hmag, 30, facecolor='gray', align='mid')
xticks(range(7,13))
pylab.rc("axes", linewidth=8.0)
pylab.rc("lines", markeredgewidth=2.0)
plt.xlabel('H mag', fontsize=14)
plt.ylabel('# of targets', fontsize=14)
pylab.xticks(fontsize=15)
pylab.yticks(fontsize=15)
plt.grid(True)
plt.savefig('hmag_histogram.eps', facecolor='w', edgecolor='w', format='eps')
plt.show()
```

Response:
```
plt.hist(hmag, 30, range=[6.5, 12.5], facecolor='gray', align='mid')
```


Question:
how to save an array as a grayscale image with matplotlib/numpy? I am trying to save a numpy array of dimensions 128x128 pixels into a grayscale image. I simply thought that the pyplot.imsave function would do the job but it's not, it somehow converts my array into an RGB image. I tried to force the colormap to Gray during conversion but eventhough the saved image appears in grayscale, it still has a 128x128x4 dimension. Here is a code sample I wrote to show the behaviour :
```
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mplimg
from matplotlib import cm

x_tot = 10e-3
nx = 128

x = np.arange(-x_tot/2, x_tot/2, x_tot/nx)

[X, Y] = np.meshgrid(x,x)
R = np.sqrt(X**2 + Y**2)

diam = 5e-3
I = np.exp(-2*(2*R/diam)**4)

plt.figure()
plt.imshow(I, extent = [-x_tot/2, x_tot/2, -x_tot/2, x_tot/2])

print I.shape

plt.imsave('image.png', I)
I2 = plt.imread('image.png')
print I2.shape

mplimg.imsave('image2.png',np.uint8(I), cmap = cm.gray)
testImg = plt.imread('image2.png')
print testImg.shape
```
In both cases the results of the "print" function are (128,128,4). Can anyone explain why the imsave function is creating those dimensions eventhough my input array is of a luminance type? And of course, does anyone have a solution to save the array into a standard grayscale format? Thanks!

Response:
With PIL it should work like this
```
from PIL import Image

I8 = (((I - I.min()) / (I.max() - I.min())) * 255.9).astype(np.uint8)

img = Image.fromarray(I8)
img.save("file.png")
```


Question:
Why set_xticks doesn't set the labels of ticks?
```
import matplotlib.pyplot as plt

x = range(1, 7)
y = (220, 300, 300, 290, 320, 315)

def test(axes):
    axes.bar(x, y)
    axes.set_xticks(x, [i+100 for i in x])

fig, (ax1, ax2) = plt.subplots(1, 2)
test(ax1)
test(ax2)
```
I am expecting the xlabs as 101, 102 ... However, if i switch to use plt.xticks(x, [i+100 for i in x]) and rewrite the function explicitly, it works.

Response:
.set_xticks() on the axes will set the locations and set_xticklabels() will set the displayed text.
```
def test(axes):
    axes.bar(x,y)
    axes.set_xticks(x)
    axes.set_xticklabels([i+100 for i in x])
```


Question:
Title for matplotlib legend I know it seems fairly redundant to have a title for a legend, but is it possible using matplotlib? Here's a snippet of the code I have:
```
import matplotlib.patches as mpatches
import matplotlib.pyplot as plt

one = mpatches.Patch(facecolor='#f3f300', label='label1', linewidth = 0.5, edgecolor = 'black')
two = mpatches.Patch(facecolor='#ff9700', label = 'label2', linewidth = 0.5, edgecolor = 'black')
three = mpatches.Patch(facecolor='#ff0000', label = 'label3', linewidth = 0.5, edgecolor = 'black')

legend = plt.legend(handles=[one, two, three], loc = 4, fontsize = 'small', fancybox = True)

frame = legend.get_frame() #sets up for color, edge, and transparency
frame.set_facecolor('#b4aeae') #color of legend
frame.set_edgecolor('black') #edge color of legend
frame.set_alpha(1) #deals with transparency
plt.show()
```
I would want the title of the legend above label1. For reference, this is the output:

Response:
Add the title parameter to the this line:
```
legend = plt.legend(handles=[one, two, three], title="title",
                    loc=4, fontsize='small', fancybox=True)
```
See also the official docs for the legend constructor.


Question:
Set axis tight only to x or y axis I have a plot look like this: Obviously, the left and right side is a waste of space, so I set
```
plt.axis('tight')
```
But this gives me plot like this: The xlim looks right now, but the ylim is too tight for the plot. I'm wondering, if I can only set axis(tight) only to x axis in my case? So the plot may look something like this: It's certainly possible that I can do this manually by
```
plt.gca().set_xlim(left=-10, right=360)
```
But I'm afraid this is not a very elegant solution.

Response:
You want to use matplotlib's autoscale method from the matplotlib.axes.Axes class. Using the functional API, you apply a tight x axis using
```
plt.autoscale(enable=True, axis='x', tight=True)
```
or if you are using the object oriented API you would use
```
ax = plt.gca()  # only to illustrate what `ax` is
ax.autoscale(enable=True, axis='x', tight=True)
```
For completeness, the axis kwarg can take 'x', 'y', or 'both', where the default is 'both'.


Question:
pandas plot value counts barplot in descending manner [duplicate] This question already has answers here: Sorted bar charts with pandas/matplotlib or seaborn (2 answers) Closed 7 years ago. I have a dataframe where i am trying to count the occurrence of each value. I plot it as horizontal bar but cant get it to be sorted.
```
df = pd.DataFrame(['A','A','A','B','B','C'],columns = ['letters'])

df.value_counts()

A 3
B 2
C 1
```
How can i get it sorted in a descending manner?

Response:
You can do it by changing your plotting line like this
```
df.letters.value_counts().sort_values().plot(kind = 'barh')
```


Question: how to use 'extent' in matplotlib.pyplot.imshow I managed to plot my data and would like to add a background image (map) to it. Data is plotted by the long/lat values and I have the long/lat values for the image's three corners (top left, top right and bottom left) too. I am trying to figure out how to use 'extent' option with imshow. However, the examples I found don't explain how to assign x and y for each corner ( in my case I have the information for three corners). How can I assign the location of three corners for the image when adding it to the plot? Thanks

Response: Specify, in the coordinates of your current axis, the corners of the rectangle that you want the image to be pasted over Extent defines the left and right limits, and the bottom and top limits. It takes four values like so: extent=[horizontal_min,horizontal_max,vertical_min,vertical_max]. Assuming you have longitude along the horizontal axis, then use extent=[longitude_top_left,longitude_top_right,latitude_bottom_left,latitude_top_left]. longitude_top_left and longitude_bottom_left should be the same, latitude_top_left and latitude_top_right should be the same, and the values within these pairs are interchangeable. If your first element of your image should be plotted in the lower left, then use the origin='lower' imshow option as well, otherwise the 'upper' default is what you want.


Question:
Matplotlib - Tcl_AsyncDelete: async handler deleted by the wrong thread? I'm asking this question because I can't solve one problem in Python/Django (actually in pure Python it's ok) which leads to RuntimeError: tcl_asyncdelete async handler deleted by the wrong thread. This is somehow related to the way how I render matplotlib plots in Django. The way I do it is:
```
...
import matplotlib.pyplot as plt
...
fig = plt.figure()
...
plt.close()
```
I extremely minimized my code. But the catch is - even if I have just one line of code:
```
fig = plt.figure()
```
I see this RuntimeError happening. I hope I could solve the problem, If I knew the correct way of closing/cleaning/destroying plots in Python/Django.

Response:
By default matplotlib uses TK gui toolkit, when you're rendering an image without using the toolkit (i.e. into a file or a string), matplotlib still instantiates a window that doesn't get displayed, causing all kinds of problems. In order to avoid that, you should use an Agg backend. It can be activated like so --
```
import matplotlib
matplotlib.use('Agg')
from matplotlib import pyplot
```
For more information please refer to matplotlib documentation -- http://matplotlib.org/faq/howto_faq.html#matplotlib-in-a-web-application-server


Question:
Extract csv file specific columns to list in Python What I'm trying to do is plot the latitude and longitude values of specific storms on a map using matplotlib,basemap,python, etc. My problem is that I'm trying to extract the latitude, longitude, and name of the storms on map but I keep getting errors between lines 41-44 where I try to extract the columns into the list. Here is what the file looks like:
```
1957,AUDREY,HU, 21.6N, 93.3W
1957,AUDREY,HU,22.0N,  93.4W
1957,AUDREY,HU,22.6N,  93.5W
1957,AUDREY,HU,23.2N,  93.6W
```
I want the list to look like the following:
```
latitude = [21.6N,22.0N,23.4N]
longitude = [93.3W, 93.5W,93.8W]
name = ["Audrey","Audrey"]
```
Here's what I have so far:
```
data = np.loadtxt('louisianastormb.csv',dtype=np.str,delimiter=',',skiprows=1)
'''print data'''

data = np.loadtxt('louisianastormb.csv',dtype=np.str,delimiter=',',skiprows=0)

f= open('louisianastormb.csv', 'rb')
reader = csv.reader(f, delimiter=',')
header = reader.next()
zipped = zip(*reader)

latitude = zipped[3]
longitude = zipped[4]
names = zipped[1]
x, y = m(longitude, latitude)
```
Here's the last error message/traceback I received: Traceback (most recent call last): File "/home/darealmzd/lstorms.py", line 42, in header = reader.next() _csv.Error: new-line character seen in unquoted field - do you need to open the file in universal-newline mode?

Response:
This looks like a problem with line endings in your code. If you're going to be using all these other scientific packages, you may as well use Pandas for the CSV reading part, which is both more robust and more useful than just the csv module:
```
import pandas
colnames = ['year', 'name', 'city', 'latitude', 'longitude']
data = pandas.read_csv('test.csv', names=colnames)
```
If you want your lists as in the question, you can now do:
```
names = data.name.tolist()
latitude = data.latitude.tolist()
longitude = data.longitude.tolist()
```


Question:
Plotting dates on the x-axis I am trying to plot information against dates. I have a list of dates in the format "01/02/1991". I converted them by doing the following:
```
x = parser.parse(date).strftime('%Y%m%d'))
```
which gives 19910102 Then I tried to use num2date
```
import matplotlib.dates as dates
new_x = dates.num2date(x)
```
Plotting:
```
plt.plot_date(new_x, other_data, fmt="bo", tz=None, xdate=True)
```
But I get an error. It says "ValueError: year is out of range". Any solutions?

Response:
You can do this more simply using plot() instead of plot_date(). First, convert your strings to instances of Python datetime.date:
```
import datetime as dt

dates = ['01/02/1991','01/03/1991','01/04/1991']
x = [dt.datetime.strptime(d,'%m/%d/%Y').date() for d in dates]
y = range(len(x)) # many thanks to Kyss Tao for setting me straight here
```
Then plot:
```
import matplotlib.pyplot as plt
import matplotlib.dates as mdates

plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%m/%d/%Y'))
plt.gca().xaxis.set_major_locator(mdates.DayLocator())
plt.plot(x,y)
plt.gcf().autofmt_xdate()
```
Result:


Question:
What is the difference between set_xlim and set_xbound? From the help: set_xlim: Set the data limits for the xaxis. set_xbound: Set the lower and upper numerical bounds of the x-axis. That is not very clear, so let’s say that I plot something:
```py
import matplotlib.pylab as plt
fig, ax = plt.subplots(1, 1)
ax.plot(xrange(10), xrange(10))
```
Now, either I do:
```py
ax.set_xlim(2, 7)
```
or:
```py
ax.set_xbound(2, 7)
```
I do not see the difference. I can dragg the plot, all the line is ploted between 0 and 9.

Response:
The bound can changes automatically, if you later plot something that is not within the bound. In contrast, limits are fixed and do not change automatically.
```
import pylab as p

t = p.arange(0.0, 2.0, 0.01)
s = p.sin(2*p.pi*t)

ax=p.subplot(111)
ax.plot(t, s, color='r',linewidth=1.0)
ax.set_ylim(-1,1)
ax.plot(t, s+1, color='g',linewidth=1.0, label="Graph2")
p.show()

ax=p.subplot(111)
ax.plot(t, s, color='r',linewidth=1.0)
ax.set_ybound(-1,1)
ax.plot(t, s+1, color='g',linewidth=1.0, label="Graph2")
p.show()
```


Question: Plot correlation matrix using pandas I have a data set with huge number of features, so analysing the correlation matrix has become very difficult. I want to plot a correlation matrix which we get using dataframe.corr() function from pandas library. Is there any built-in function provided by the pandas library to plot this matrix?

Response:
If your main goal is to visualize the correlation matrix, rather than creating a plot per se, the convenient pandas styling options is a viable built-in solution:
```
import pandas as pd
import numpy as np

rs = np.random.RandomState(0)
df = pd.DataFrame(rs.rand(10, 10))
corr = df.corr()
corr.style.background_gradient(cmap='coolwarm')
# 'RdBu_r', 'BrBG_r', & PuOr_r are other good diverging colormaps
```
Note that this needs to be in a backend that supports rendering HTML, such as the JupyterLab Notebook. Styling You can easily limit the digit precision (this is now .format(precision=2) in pandas 2.*):
```
corr.style.background_gradient(cmap='coolwarm').set_precision(2)
```
Or get rid of the digits altogether if you prefer the matrix without annotations:
```
corr.style.background_gradient(cmap='coolwarm').set_properties(**{'font-size': '0pt'})
```
The styling documentation also includes instructions of more advanced styles, such as how to change the display of the cell the mouse pointer is hovering over. Time comparison In my testing, style.background_gradient() was 4x faster than plt.matshow() and 120x faster than sns.heatmap() with a 10x10 matrix. Unfortunately it doesn't scale as well as plt.matshow(): the two take about the same time for a 100x100 matrix, and plt.matshow() is 10x faster for a 1000x1000 matrix. Saving There are a few possible ways to save the stylized dataframe: Return the HTML by appending the render() method and then write the output to a file. Save as an .xslx file with conditional formatting by appending the to_excel() method. Combine with imgkit to save a bitmap Take a screenshot (like I have done here). Normalize colors across the entire matrix (pandas >= 0.24) By setting axis=None, it is now possible to compute the colors based on the entire matrix rather than per column or per row:
```
corr.style.background_gradient(cmap='coolwarm', axis=None)
```
Single corner heatmap Since many people are reading this answer I thought I would add a tip for how to only show one corner of the correlation matrix. I find this easier to read myself, since it removes the redundant information.
```
# Fill diagonal and upper half with NaNs
mask = np.zeros_like(corr, dtype=bool)
mask[np.triu_indices_from(mask)] = True
corr[mask] = np.nan
(corr
 .style
 .background_gradient(cmap='coolwarm', axis=None, vmin=-1, vmax=1)
 .highlight_null(color='#f1f1f1')  # Color NaNs grey
 .format(precision=2))
```


Question:
Multiple datasets on the same scatter plot I want to plot multiple data sets on the same scatter plot:
```
cases = scatter(x[:4], y[:4], s=10, c='b', marker="s")
controls = scatter(x[4:], y[4:], s=10, c='r', marker="o")

show()
```
The above only shows the most recent scatter() I've also tried:
```
plt = subplot(111)
plt.scatter(x[:4], y[:4], s=10, c='b', marker="s")
plt.scatter(x[4:], y[4:], s=10, c='r', marker="o")
show()
```

Response:
You need a reference to an Axes object to keep drawing on the same subplot.
```
import matplotlib.pyplot as plt

x = range(100)
y = range(100,200)
fig = plt.figure()
ax1 = fig.add_subplot(111)

ax1.scatter(x[:4], y[:4], s=10, c='b', marker="s", label='first')
ax1.scatter(x[40:],y[40:], s=10, c='r', marker="o", label='second')
plt.legend(loc='upper left')
plt.show()
```


Question: Plotting pandas timedelta I have a pandas dataframe that has two datetime64 columns and one timedelta64 column that is the difference between the two columns. I'm trying to plot a histogram of the timedelta column to visualize the time differences between the two events. However, just using df['time_delta'] results in: TypeError: ufunc add cannot use operands with types dtype(' df2 = df1['time_delta'].astype(float) results in: TypeError: cannot astype a timedelta from [timedelta64[ns]] to [float64] How would one create a histogram of pandas timedelta data?

Response:
Here are ways to convert timedeltas, docs are here
```

```python
pd.to_timedelta(np.arange(5),unit='d')+pd.to_timedelta(1,unit='s')
#Output
#0   0 days, 00:00:01
#1   1 days, 00:00:01
#2   2 days, 00:00:01
#3   3 days, 00:00:01
#4   4 days, 00:00:01
#dtype: timedelta64[ns]
#```
#Convert to seconds (is an exact conversion)
#```
```

```python
(pd.to_timedelta(np.arange(5),unit='d')+pd.to_timedelta(1,unit='s')).astype('timedelta64[s]')
#Output
#0         1
#1     86401
#2    172801
#3    259201
#4    345601
#dtype: float64
#```
#Convert using astype will round to that unit
#```
```

```python
(pd.to_timedelta(np.arange(5),unit='d')+pd.to_timedelta(1,unit='s')).astype('timedelta64[D]')
#Output
#0    0
#1    1
#2    2
#3    3
#4    4
#dtype: float64
#```
#Division will give an exact repr
#```
```

```python
(pd.to_timedelta(np.arange(5),unit='d')+pd.to_timedelta(1,unit='s')) / np.timedelta64(1,'D')
#Output
#0    0.000012
#1    1.000012
#2    2.000012
#3    3.000012
#4    4.000012
#dtype: float64
#```
```


Question:
How to pass rgb color values to eventplot I'm simply trying to plot some tick marks with a specific color using matplotlib's eventplot. I'm running Python 3 in Jupyter notebook with %matplotlib inline. Here's an example code:
```
import numpy as np
import matplotlib.pyplot as plt
spikes = 100*np.random.random(100)
plt.eventplot(spikes, orientation='horizontal', linelengths=0.9, color=[0.3,0.3,0.5])
```
It outputs the following error:
```
ValueError: colors and positions are unequal sized sequences
```
The error occurs presumably because I am not providing a list of colors of the same length as the data (but I wan't them to all just be the same color!). It also gives an error when I use a color string like 'crimson' or 'orchid'. But it works when I use a simple one-letter string like 'r'. Am I really restricted to just using the extremely limited set of one-letter color strings 'r','b','g','k','m','y', etc... or making a long color list when using this eventplot?

Response:
According to the docs: you can pass an (r, g, b) or (r, g, b, a) tuple, where each of r, g, b and a are in the range [0,1].
```
import numpy as np
import matplotlib.pyplot as plt

spikes = 100*np.random.random(100)
plt.eventplot(spikes, orientation='horizontal', linelengths=0.9, color = [(0.3,0.3,0.5)])

plt.show()
```


Question:
How do I change the font size of ticks of matplotlib.pyplot.colorbar.ColorbarBase? I would like to know how to change the font size of ticks of ColorbarBase of matplotlib. The following lines are a relevant part in my analysis script, in which ColorbarBase is used.
```
import matplotlib.pyplot as plt
from matplotlib.colors import LogNorm
import matplotlib as mpl

axcb = fig.add_axes([0.9, 0.135, 0.02, 0.73])

cb = mpl.colorbar.ColorbarBase(axcb, norm=LogNorm(vmin=7e-5, vmax=1), cmap=plt.cm.CMRmap)
cb.set_label("Relative Photon Intensity", labelpad=-1, size=14)
```
I am using matplotlib ver 1.4.3 with Python 2.7 on OS X.

Response:
You can change the tick size using:
```
font_size = 14 # Adjust as appropriate.
cb.ax.tick_params(labelsize=font_size)
```
See the docs for ax.tick_params here for more parameters that can be modified.


Question:
How to edit a seaborn legend title and labels for figure-level functions I've created this plot using Seaborn and a pandas dataframe (data): My code:
```py
import seaborn as sns

g = sns.lmplot('credibility', 'percentWatched', data=data, hue='millennial', markers=["+", "."])
```
You may notice the plot's legend title is simply the variable name ('millennial') and the legend items are its values (0, 1). How can I edit the legend's title and labels? Ideally, the legend title would be 'Generation' and the labels would be "Millennial" and "Older Generations".

Response:
If legend_out is set to True then legend is available through the g._legend property and it is a part of a figure. Seaborn legend is standard matplotlib legend object. Therefore you may change legend texts. Tested in python 3.8.11, matplotlib 3.4.3, seaborn 0.11.2
```py
import seaborn as sns

# load the tips dataset
tips = sns.load_dataset("tips")

# plot
g = sns.lmplot(x="total_bill", y="tip", hue="smoker", data=tips, markers=["o", "x"], facet_kws={'legend_out': True})

# title
new_title = 'My title'
g._legend.set_title(new_title)
# replace labels
new_labels = ['label 1', 'label 2']
for t, l in zip(g._legend.texts, new_labels):
    t.set_text(l)
```
Another situation if legend_out is set to False. You have to define which axes has a legend (in below example this is axis number 0):
```py
g = sns.lmplot(x="total_bill", y="tip", hue="smoker", data=tips, markers=["o", "x"], facet_kws={'legend_out': False})

# check axes and find which is have legend
leg = g.axes.flat[0].get_legend()
new_title = 'My title'
leg.set_title(new_title)
new_labels = ['label 1', 'label 2']
for t, l in zip(leg.texts, new_labels):
    t.set_text(l)
```
Moreover you may combine both situations and use this code:
```py
g = sns.lmplot(x="total_bill", y="tip", hue="smoker", data=tips, markers=["o", "x"], facet_kws={'legend_out': True})

# check axes and find which is have legend
for ax in g.axes.flat:
    leg = g.axes.flat[0].get_legend()
    if not leg is None: break
# or legend may be on a figure
if leg is None: leg = g._legend

# change legend texts
new_title = 'My title'
leg.set_title(new_title)
new_labels = ['label 1', 'label 2']
for t, l in zip(leg.texts, new_labels):
    t.set_text(l)
```
This code works for any seaborn plot which is based on Grid class.


Question:
Changing matplotlib subplot size/position after axes creation Is it possible to set the size/position of a matplotlib subplot after the axes are created? I know that I can do:
```
import matplotlib.pyplot as plt

ax = plt.subplot(111)
ax.change_geometry(3,1,1)
```
to put the axes on the top row of three. But I want the axes to span the first two rows. I have tried this:
```
import matplotlib.gridspec as gridspec

ax = plt.subplot(111)
gs = gridspec.GridSpec(3,1)
ax.set_subplotspec(gs[0:2])
```
but the axes still fill the whole window. Update for clarity I want to change the position of an existing axes instance rather than set it when it is created. This is because the extent of the axes will be modified each time I add data (plotting data on a map using cartopy). The map may turn out tall and narrow, or short and wide (or something in between). So the decision on the grid layout will happen after the plotting function.

Response:
Thanks to Molly pointing me in the right direction, I have a solution:
```
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec

fig = plt.figure()

ax = fig.add_subplot(111)

gs = gridspec.GridSpec(3,1)
ax.set_position(gs[0:2].get_position(fig))
ax.set_subplotspec(gs[0:2])              # only necessary if using tight_layout()

fig.add_subplot(gs[2])

fig.tight_layout()                       # not strictly part of the question

plt.show()
```


Question:
Setting axis limits in matplotlib pyplot I have two subplots in a figure. I want to set the axes of the second subplot such that it has the same limits as the first subplot (which changes depending on the values plotted).
```
import matplotlib.pyplot as plt

plt.figure(1, figsize=(10, 20))

## First subplot: Mean value in each period (mean over replications)
plt.subplot(211, axisbg='w')
plt.plot(time,meanVector[0:xMax], color='#340B8C',
         marker='x', ms=4, mec='#87051B', markevery=(asp, 2 * asp))
plt.xticks(numpy.arange(0, T + 1, jump), rotation=-45)
plt.axhline(y = Results[0], color='#299967', ls='--')
plt.ylabel('Mean Value')
plt.xlabel('Time')
plt.grid(True)

## Second subplot: moving average for determining warm-up period
## (Welch method)

plt.subplot(212)
plt.plot(time[0:len(yBarWvector)],yBarWvector, color='#340B8C')
plt.xticks(numpy.arange(0, T + 1, jump), rotation=-45)
plt.ylabel('yBarW')
plt.xlabel('Time')
plt.xlim((0, T))
plt.grid(True)
```
In the second subplot, what should be the arguments for plt.ylim() function? I tried defining
```
ymin, ymax = plt.ylim()
```
in the first subplot and then set
```
plt.ylim((ymin,ymax))
```
in the second subplot. But that did not work, because the returned value ymax is the maximum value taken by the y variable (mean value) in the first subplot and not the upper limit of the y-axis.

Response:
Your proposed solution should work, especially if the plots are interactive (they will stay in sync if one changes). As alternative, you can manually set the y-limits of the second axis to match that of the first. Example:
```
from pylab import *

x = arange(0.0, 2.0, 0.01)
y1 = 3*sin(2*pi*x)
y2 = sin(2*pi*x)

figure()
ax1 = subplot(211)
plot(x, y1, 'b')

subplot(212)
plot(x, y2, 'g')
ylim( ax1.get_ylim() )        # set y-limit to match first axis

show()
```


Question:
Python: Creating a 2D histogram from a numpy matrix I'm new to python. I have a numpy matrix, of dimensions 42x42, with values in the range 0-996. I want to create a 2D histogram using this data. I've been looking at tutorials, but they all seem to show how to create 2D histograms from random data and not a numpy matrix. So far, I have imported:
```
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import colors
```
I'm not sure if these are correct imports, I'm just trying to pick up what I can from tutorials I see. I have the numpy matrix M with all of the values in it (as described above). In the end, i want it to look something like this: obviously, my data will be different, so my plot should look different. Can anyone give me a hand? Edit: For my purposes, Hooked's example below, using matshow, is exactly what I'm looking for.

Response:
If you have the raw data from the counts, you could use plt.hexbin to create the plots for you (IMHO this is better than a square lattice): Adapted from the example of hexbin:
```
import numpy as np
import matplotlib.pyplot as plt

n = 100000
x = np.random.standard_normal(n)
y = 2.0 + 3.0 * x + 4.0 * np.random.standard_normal(n)
plt.hexbin(x,y)

plt.show()
```
If you already have the Z-values in a matrix as you mention, just use plt.imshow or plt.matshow:
```
XB = np.linspace(-1,1,20)
YB = np.linspace(-1,1,20)
X,Y = np.meshgrid(XB,YB)
Z = np.exp(-(X**2+Y**2))
plt.imshow(Z,interpolation='none')
```


Question:
Plot pandas dates in matplotlib I have a fixed-width data file containing dates, but when I try to plot the data the dates are not displayed properly on the x-axis. My files looks like
```
2014-07-10 11:49:14.377102    45
2014-07-10 11:50:14.449150    45
2014-07-10 11:51:14.521168    21
2014-07-10 11:52:14.574241     8
2014-07-10 11:53:14.646137    11
2014-07-10 11:54:14.717688    14
```
etc and I use pandas to read in the file
```
#! /usr/bin/env python
import pandas as pd
import matplotlib.pyplot as plt
data = pd.read_fwf('myfile.log',header=None,names=['time','amount'],widths=[27,5])
data.time = pd.to_datetime(data['time'], format='%Y-%m-%d %H:%M:%S.%f')
plt.plot(data.time,data.amount)
plt.show()
```
So I suppose the issue here is conversion from pandas to matplotlib datetime, How would one do a conversion? I also tried with pandas directly:
```
data.time = pd.to_datetime(data['time'], format='%Y-%m-%d %H:%M:%S.%f')
data.set_index('time') # Fails!!
data.time.plot()
```
but this fails with TypeError: Empty 'Series': no numeric data to plot

Response:
If you use a list containing the column name(s) instead of a string, data.set_index will work The following should show the dates on x-axis:
```
#! /usr/bin/env python
import pandas as pd
import matplotlib.pyplot as plt
data = pd.read_fwf('myfile.log',header=None,names=['time','amount'],widths=[27,5])
data.time = pd.to_datetime(data['time'], format='%Y-%m-%d %H:%M:%S.%f')
data.set_index(['time'],inplace=True)
data.plot()

#OR
plt.plot(data.index, data.amount)
```


Question:
Map values to colors in matplotlib I have a list of numbers as follows:
```
lst = [1.9378076554115014, 1.2084586588892861, 1.2133096565896173,
       1.2427632053442292, 1.1809971732733273, 0.91960143581348919,
       1.1106310149587162, 1.1106310149587162, 1.1527004351293346,
       0.87318084435885079, 1.1666132876686799, 1.1666132876686799]
```
I want to convert these numbers to colors for display. I want gray scale but when I am using these numbers as it is, it gives me an error:
```
ValueError: to_rgba: Invalid rgba arg "1.35252299785"
to_rgb: Invalid rgb arg "1.35252299785"
gray (string) must be in range 0-1
```
...which I understand is due to it exceeding 1. I next tried to divide the items in the list with the highest number in the list to give values less than 1. But this gives a very narrow color scale with hardly any difference between values. Is there any way in which I can give some min and max range to colors and convert these values to color? I am using matplotlib.

Response:
The matplotlib.colors module is what you are looking for. This provides a number of classes to map from values to colourmap values.
```
import matplotlib
import matplotlib.cm as cm

lst = [1.9378076554115014, 1.2084586588892861, 1.2133096565896173, 1.2427632053442292,
       1.1809971732733273, 0.91960143581348919, 1.1106310149587162, 1.1106310149587162,
       1.1527004351293346, 0.87318084435885079, 1.1666132876686799, 1.1666132876686799]

minima = min(lst)
maxima = max(lst)

norm = matplotlib.colors.Normalize(vmin=minima, vmax=maxima, clip=True)
mapper = cm.ScalarMappable(norm=norm, cmap=cm.Greys_r)

for v in lst:
    print(mapper.to_rgba(v))
```
The general approach is find the minima and maxima in your data. Use these to create a Normalize instance (other normalisation classes are available, e.g. log scale). Next you create a ScalarMappable using the Normalize instance and your chosen colormap. You can then use mapper.to_rgba(v) to map from an input value v, via your normalised scale, to a target color.
```
for v in sorted(lst):
    print("%.4f: %.4f" % (v, mapper.to_rgba(v)[0]) )
```
Produces the output:
```
0.8732: 0.0000
0.9196: 0.0501
1.1106: 0.2842
1.1106: 0.2842
1.1527: 0.3348
1.1666: 0.3469
1.1666: 0.3469
1.1810: 0.3632
1.2085: 0.3875
1.2133: 0.3916
1.2428: 0.4200
1.9378: 1.0000
```
The matplotlib.colors module documentation has more information if needed.


Question: Partially transparent scatter plot, but with a solid color bar In Python, with Matplotlib, how to simply do a scatter plot with transparency (alpha < 1), but with a color bar that represents their color value, but has alpha = 1? Here is what one gets, with from pylab import *; scatter(range(10), arange(0, 100, 10), c=range(10), alpha=0.2); color_bar = colorbar(): How can the color bar be made non-transparent? PS: I tried color_bar.set_alpha(1); draw(), but this did not do anything…

Response:
Alright, I found one way to do it, that looks relatively clean: (using the ColorBar object from the question)
```
color_bar.set_alpha(1)
color_bar.draw_all()
# pylab.draw() or pyplot.draw() might be necessary
```
It would be great to get a confirmation that this is the most robust way to proceed, though! :)


Question:
How to drop connecting lines where the function is discontinuous I'm plotting some functions that have several discontinuities. Each function is given as a list. I want to connect points with lines only where the function is continuous. Here is a simplified example of what plot is doing.
```
x=linspace(0,1,100)
y=zeros(100)
y[x<0.5] = x[x<0.5]
y[x>=0.5] = 1 + x[x>=0.5]
plot(x, y, '-o')
```
There is a discontinuity at x=0.5, but plot connects all points with lines regardless. My functions are different of course. They typically have several discontinuities in different places. The criterion for the discontinuity is simple. Say, if the function jumps by more than 0.5, I assume it is discontinuous at that point. Is there an option in plot to tell it to drop the connecting lines between the points where the function is discontinuous? I recall being able to do that easily with gnuplot.

Response:
use nan to break the line into multiple segments:
```
import numpy as np
from pylab import *
x=linspace(0,1,100)
y=zeros(100)
y[x<0.5] = x[x<0.5]
y[x>=0.5] = 1 + x[x>=0.5]

pos = np.where(np.abs(np.diff(y)) >= 0.5)[0]

x[pos] = np.nan
y[pos] = np.nan

plot(x, y, '-o')
```
Edit: to insert nan at discontinuities:
```
pos = np.where(np.abs(np.diff(y)) >= 0.5)[0]+1
x = np.insert(x, pos, np.nan)
y = np.insert(y, pos, np.nan)
```


Question:
Adding line to scatter plot using python's matplotlib I am using python's matplotlib and want to create a matplotlib.scatter() with additional line. The line should proceed from the lower left corner to the upper right corner independent of the scatters content. A linear regression through the data, like in this post, is not what I am looking for. Also it should be dynamically and independent of the scatter input. This should be the final plot: EDIT: Doing this got me the result:
```
# Scatter Plot
x = data_calc_hourly.temp
y =  data_obs_hourly.temp

lineStart = data_calc_hourly.temp.min()
lineEnd = data_calc_hourly.temp.max()

plt.figure()
plt.scatter(x, y, color = 'k', alpha=0.5)
plt.plot([lineStart, lineEnd], [lineStart, lineEnd], 'k-', color = 'r')
plt.xlim(lineStart, lineEnd)
plt.ylim(lineStart, lineEnd)
plt.show()
```
Is there any better way ?

Response:
This draws a diagonal line which is independent of the scatter plot data and which stays rooted to the axes even if you resize the window:
```
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.lines as mlines
import matplotlib.transforms as mtransforms

x, y = np.random.random((2, 100))*2
fig, ax = plt.subplots()
ax.scatter(x, y, c='black')
line = mlines.Line2D([0, 1], [0, 1], color='red')
transform = ax.transAxes
line.set_transform(transform)
ax.add_line(line)
plt.show()
```


Question:
Adding subplots to a subplot I'm trying to create a figure that consists of a 2x2 grid, where in each quadrant there are 2 vertically stacked subplots (i.e. a 2x1 grid). I can't seem to figure out how to achieve this, though. The closest I've gotten is using gridspec and some ugly code (see below), but because gridspec.update(hspace=X) changes the spacing for all of the subplots I'm still not where I'd like to be. Ideally what I want is to, using the picture below as an example, decrease the spacing between the subplots within each quadrant, while increasing the vertical spacing between the top and bottom quadrants (i.e. between 1-3 and 2-4). Is there a way to do this (with or without using gridspec)? What I originally envisioned is generating each of the sub-subplot grids (i.e. each 2x1 grid) and inserting them into the larger 2x2 grid of subplots, but I haven't figured out how to add a subplot to a subplot, if there is even a way.
```
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
plt.figure(figsize=(10, 8))
gs = gridspec.GridSpec(4,2)
gs.update(hspace=0.4)
for i in range(2):
    for j in range(4):
        ax = plt.subplot(gs[j,i])
        ax.spines['top'].set_visible(False)
        ax.spines['right'].set_visible(False)
        plt.tick_params(which='both', top='off', right='off')
        if j % 2 == 0:
            ax.set_title(str(i+j+1))
            ax.plot([1,2,3], [1,2,3])
            ax.spines['bottom'].set_visible(False)
            ax.get_xaxis().set_visible(False)
        else:
            ax.plot([1,2,3], [3,2,1])
```

Response:
You can nest your GridSpec using SubplotSpec. The outer grid will be a 2 x 2 and the inner grids will be 2 x 1. The following code should give you the basic idea.
```
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec

fig = plt.figure(figsize=(10, 8))
outer = gridspec.GridSpec(2, 2, wspace=0.2, hspace=0.2)

for i in range(4):
    inner = gridspec.GridSpecFromSubplotSpec(2, 1,
                    subplot_spec=outer[i], wspace=0.1, hspace=0.1)

    for j in range(2):
        ax = plt.Subplot(fig, inner[j])
        t = ax.text(0.5,0.5, 'outer=%d, inner=%d' % (i, j))
        t.set_ha('center')
        ax.set_xticks([])
        ax.set_yticks([])
        fig.add_subplot(ax)

fig.show()
```


Question:
matplotlib hatched fill_between without edges? I have a region I'd like to hatch which borders on an existing plot line (of the same colour) that is dashed. However, when I use fill_between the region to be hatched has a border drawn around it also. This border seems share properties with the lines that create the hatching so I cannot set edgecolour to "none" or set linestyle as "--" as the hatching is similarly affected.
```
import matplotlib.pyploy as plt
plt.plot([0,1],[0,1],ls="--",c="b")
plt.fill_between([0,1],[0,1],color="none",hatch="X",edgecolor="b")
plt.show()
```
In this example I'd want the diagonal line from 0,0 to 1,1 to be dashed. Many thanks in advance.

Response:
>2.0.1 Update As commented by @CatherineHolloway you need to use facecolor instead of color now:
```
import matplotlib.pyplot as plt
plt.plot([0,1],[0,1],ls="--",c="b")
plt.fill_between([0,1],[0,1], facecolor="none", hatch="X", edgecolor="b", linewidth=0.0)
plt.show()
```
Former answer This seems to do the trick!
```
import matplotlib.pyplot as plt
plt.plot([0,1],[0,1],ls="--",c="b")
plt.fill_between([0,1],[0,1], color="none", hatch="X", edgecolor="b", linewidth=0.0)
plt.show()
```


Question:
Confusion between numpy, scipy, matplotlib and pylab Numpy, scipy, matplotlib, and pylab are common terms among they who use python for scientific computation. I just learn a bit about pylab, and I got confused. Whenever I want to import numpy, I can always do:
```
import numpy as np
```
I just consider, that once I do
```
from pylab import *
```
the numpy will be imported as well (with np alias). So basically the second one does more things compared to the first one. There are few things I want to ask: Is it right that pylab is just a wrapper for numpy, scipy and matplotlib? As np is the numpy alias in pylab, what is the scipy and matplotlib alias in pylab? (as far as I know, plt is alias of matplotlib.pyplot, but I don't know the alias for the matplotlib itself)

Response: No, pylab is part of matplotlib (in matplotlib.pylab) and tries to give you a MatLab like environment. matplotlib has a number of dependencies, among them numpy which it imports under the common alias np. scipy is not a dependency of matplotlib. If you run ipython --pylab an automatic import will put all symbols from matplotlib.pylab into global scope. Like you wrote numpy gets imported under the np alias. Symbols from matplotlib are available under the mpl alias.


Question:
How to change the color of a single bar in a bar plot Supposely, I have the bar chart as below: Any ideas on how to set different colors for each carrier? As for example, AK would be Red, GA would be Green, etc? I am using Pandas and matplotlib in Python
```

```python
f=plt.figure()
```

```python
ax=f.add_subplot(1,1,1)
```

```python
ax.bar([1,2,3,4], [1,2,3,4])
#Output
#<Container object of 4 artists>
```

```python
ax.get_children()
#Output
#[<matplotlib.axis.XAxis object at 0x6529850>, <matplotlib.axis.YAxis object at 0x78460d0>,  <matplotlib.patches.Rectangle object at 0x733cc50>, <matplotlib.patches.Rectangle object at 0x733cdd0>, <matplotlib.patches.Rectangle object at 0x777f290>, <matplotlib.patches.Rectangle object at 0x777f710>, <matplotlib.text.Text object at 0x7836450>, <matplotlib.patches.Rectangle object at 0x7836390>, <matplotlib.spines.Spine object at 0x6529950>, <matplotlib.spines.Spine object at 0x69aef50>, <matplotlib.spines.Spine object at 0x69ae310>, <matplotlib.spines.Spine object at 0x69aea50>]
```

```python
ax.get_children()[2].set_color('r') #You can also try to locate the first patches.Rectangle object instead of direct calling the index.
#Output
#```
#For the suggestions above, how do exactly we could enumerate ax.get_children() and check if the object type is rectangle? So if the object is rectangle, we would assign different random color?
```

Response:
Simple, just use .set_color
```

```python
barlist=plt.bar([1,2,3,4], [1,2,3,4])
```

```python
barlist[0].set_color('r')
```

```python
plt.show()
#Output
#```
#For your new question, not much harder either, just need to find the bar from your axis, an example:
#```
```

```python
f=plt.figure()
```

```python
ax=f.add_subplot(1,1,1)
```

```python
ax.bar([1,2,3,4], [1,2,3,4])
#Output
#<Container object of 4 artists>
```

```python
ax.get_children()
#Output
#[<matplotlib.axis.XAxis object at 0x6529850>,
# <matplotlib.axis.YAxis object at 0x78460d0>,
# <matplotlib.patches.Rectangle object at 0x733cc50>,
# <matplotlib.patches.Rectangle object at 0x733cdd0>,
# <matplotlib.patches.Rectangle object at 0x777f290>,
# <matplotlib.patches.Rectangle object at 0x777f710>,
# <matplotlib.text.Text object at 0x7836450>,
# <matplotlib.patches.Rectangle object at 0x7836390>,
# <matplotlib.spines.Spine object at 0x6529950>,
# <matplotlib.spines.Spine object at 0x69aef50>,
# <matplotlib.spines.Spine object at 0x69ae310>,
# <matplotlib.spines.Spine object at 0x69aea50>]
```

```python
ax.get_children()[2].set_color('r')
#Output
# #You can also try to locate the first patches.Rectangle object
# #instead of direct calling the index.
#```
#If you have a complex plot and want to identify the bars first, add those:
#```
```

```python
import matplotlib
```

```python
childrenLS=ax.get_children()
```

```python
barlist=filter(lambda x: isinstance(x, matplotlib.patches.Rectangle), childrenLS)
#Output
#[<matplotlib.patches.Rectangle object at 0x3103650>,
# <matplotlib.patches.Rectangle object at 0x3103810>,
# <matplotlib.patches.Rectangle object at 0x3129850>,
# <matplotlib.patches.Rectangle object at 0x3129cd0>,
# <matplotlib.patches.Rectangle object at 0x3112ad0>]
#```
```


Question:
Store mouse click event coordinates with matplotlib I am trying to implement a simple mouse click event in matplotlib. I wish to plot a figure then use the mouse to select the lower and upper limits for integration. So far I am able to print the coordinates to screen but not store them for later use in the program. I would also like to exit the connection to the figure after the second mouse click. Below is the code which currently plots and then prints the coordinates. My Question(s): How can I store coordinates from the figure to list? i.e. click = [xpos, ypos] Is it possible to get two sets of x coordinates in order to do a simple integration over that section of line?
```py
import numpy as np
import matplotlib.pyplot as plt

x = np.arange(-10,10)
y = x**2

fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(x,y)

def onclick(event):
    global ix, iy
    ix, iy = event.xdata, event.ydata
    print 'x = %d, y = %d'%(
        ix, iy)

    global coords
    coords = [ix, iy]

    return coords

for i in xrange(0,1):

    cid = fig.canvas.mpl_connect('button_press_event', onclick)

plt.show()
```

Response:
mpl_connect needs to be called just once to connect the event to event handler. It will start listening to click event until you disconnect. And you can use
```
fig.canvas.mpl_disconnect(cid)
```
to disconnect the event hook. What you want to do is something like:
```
import numpy as np
import matplotlib.pyplot as plt

x = np.arange(-10,10)
y = x**2

fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(x,y)

coords = []

def onclick(event):
    global ix, iy
    ix, iy = event.xdata, event.ydata
    print (f'x = {ix}, y = {iy}')

    global coords
    coords.append((ix, iy))

    if len(coords) == 2:
        fig.canvas.mpl_disconnect(cid)

    return coords
cid = fig.canvas.mpl_connect('button_press_event', onclick)
```


Question: How to change fonts in matplotlib (python)? It sounds as an easy problem but I do not find any effective solution to change the font (not the font size) in a plot made with matplotlib in python. I found a couple of tutorials to change the default font of matplotlib by modifying some files in the folders where matplotlib stores its default font - see this blog post - but I am looking for a less radical solution since I would like to use more than one font in my plot (text, label, axis label, etc).

Response:
Say you want Comic Sans for the title and Helvetica for the x label.
```
csfont = {'fontname':'Comic Sans MS'}
hfont = {'fontname':'Helvetica'}

plt.title('title',**csfont)
plt.xlabel('xlabel', **hfont)
plt.show()
```


Question: Remove the legend on a matplotlib figure To add a legend to a matplotlib plot, one simply runs legend(). How to remove a legend from a plot? (The closest I came to this is to run legend([]) in order to empty the legend from data. But that leaves an ugly white rectangle in the upper right corner.)

Response:
As of matplotlib v1.4.0rc4, a remove method has been added to the legend object. Usage:
```py
ax.get_legend().remove()
```
or
```py
legend = ax.legend(...)
...
legend.remove()
```
See here for the commit where this was introduced.


Question:
Setting a relative frequency in a matplotlib histogram I have data as a list of floats and I want to plot it as a histogram. Hist() function does the job perfectly for plotting the absolute histogram. However, I cannot figure out how to represent it in a relative frequency format - I would like to have it as a fraction or ideally as a percentage on the y-axis. Here is the code:
```
fig = plt.figure()
ax = fig.add_subplot(111)
n, bins, patches = ax.hist(mydata, bins=100, normed=1, cumulative=0)
ax.set_xlabel('Bins', size=20)
ax.set_ylabel('Frequency', size=20)
ax.legend

plt.show()
```
I thought normed=1 argument would do it, but it gives fractions that are too high and sometimes are greater than 1. They also seem to depend on the bin size, as if they are not normalized by the bin size or something. Nevertheless, when I set cumulative=1, it nicely sums up to 1. So, where is the catch? By the way, when I feed the same data into Origin and plot it, it gives me perfectly correct fractions. Thank you!

Response:
Because normed option of hist returns the density of points, e.g dN/dx What you need is something like that:
```
# assuming that mydata is an numpy array
 ax.hist(mydata, weights=np.zeros_like(mydata) + 1. / mydata.size)
 # this will give you fractions
```


Question:
Rotate tick labels in subplot I am attempting to rotate the x labels of a subplot (created using GridSpec) by 45 degrees. I have tried using axa.set_xticks() and axa.set_xticklabels, but it does not seem to work. Google wasn't helping either, since most questions concerning labels are about normal plots, and not subplots. See code below:
```
width = 20                                    # Width of the figure in centimeters
height = 15                                   # Height of the figure in centimeters
w = width * 0.393701                            # Conversion to inches
h = height * 0.393701                           # Conversion to inches

f1 = plt.figure(figsize=[w,h])
gs = gridspec.GridSpec(1, 7, width_ratios = [1.5, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0])

axa = plt.subplot(gs[0])
axa.plot(dts, z,'k', alpha=0.75, lw=0.25)
#axa.set_title('...')
axa.set_ylabel('TVDSS ' + '$[m]$', fontsize = '10' )
axa.set_xlabel('slowness 'r'$[\mu s/m]$', fontsize = '10')
axa.set_ylim(245, 260)
axa.set_xlim(650, 700)
axa.tick_params(labelsize=7)
axa.invert_yaxis()
axa.grid()
```
Any help will be greatly appreciated!

Response:
You can do it in multiple ways: Here is one solution making use of tick_params:
```
ax.tick_params(labelrotation=45)
```
Here is another solution making use of set_xticklabels:
```
ax.set_xticklabels(labels, rotation=45)
```
Here is a third solution making use of set_rotation:
```
for tick in ax.get_xticklabels():
    tick.set_rotation(45)
```


Question:
How to format axis number format to thousands with a comma How can I change the format of the numbers in the x-axis to be like 10,000 instead of 10000? Ideally, I would just like to do something like this:
```
x = format((10000.21, 22000.32, 10120.54), "#,###")
```
Here is the code:
```
import matplotlib.pyplot as plt

# create figure instance
fig1 = plt.figure(1)
fig1.set_figheight(15)
fig1.set_figwidth(20)

ax = fig1.add_subplot(2,1,1)

x = 10000.21, 22000.32, 10120.54

y = 1, 4, 15
ax.plot(x, y)

ax2 = fig1.add_subplot(2,1,2)

x2 = 10434, 24444, 31234
y2 = 1, 4, 9
ax2.plot(x2, y2)

fig1.show()
```

Response:
Use , as format specifier:
```

```python
format(10000.21, ',')
#Output
#'10,000.21'
#```
#Alternatively you can also use str.format instead of format:
#```
```

```python
'{:,}'.format(10000.21)
#Output
#'10,000.21'
#```
#With matplotlib.ticker.FuncFormatter:
#```
#...
#ax.get_xaxis().set_major_formatter(
#    matplotlib.ticker.FuncFormatter(lambda x, p: format(int(x), ',')))
#ax2.get_xaxis().set_major_formatter(
#    matplotlib.ticker.FuncFormatter(lambda x, p: format(int(x), ',')))
#fig1.show()
#```
```


Question:
How to view all colormaps available in matplotlib? I was wondering if there is a function call that can give me the name of all colormaps available in matplotlib? It used to be possible by something along the lines of (see here):
```
import matplotlib.pyplot as plt
cmaps = sorted(m for m in plt.cm.datad if not m.endswith("_r"))
```
But running this in mpl 1.5 does not return the new colormaps, such as viridis, magma and so on. On the new reference page the code actually hardcodes the names (see here) but I was wondering if a similar query to the above is still possible?

Response: plt.colormaps() returns a list of all registered colormaps. From the docs: matplotlib.pyplot.colormaps() Matplotlib provides a number of colormaps, and others can be added using register_cmap(). This function documents the built-in colormaps, and will also return a list of all registered colormaps if called. The list this returns includes viridis, magma, inferno and plasma for me in 1.5.0


Question:
Cleanest way to hide every nth tick label in matplotlib colorbar? The labels on my horizontal colorbar are too close together and I don't want to reduce text size further:
```
cbar = plt.colorbar(shrink=0.8, orientation='horizontal', extend='both', pad=0.02)
cbar.ax.tick_params(labelsize=8)
```
I'd like to preserve all ticks, but remove every other label. Most examples I've found pass a user-specified list of strings to cbar.set_ticklabels(). I'm looking for a general solution. I played around with variations of
```
cbar.set_ticklabels(cbar.get_ticklabels()[::2])
```
and
```
cbar.ax.xaxis.set_major_locator(matplotlib.ticker.MaxNLocator(nbins=4))
```
but I haven't found the magic combination. I know there must be a clean way to do this using a locator object.

Response:
For loop the ticklabels, and call set_visible():
```
for label in cbar.ax.xaxis.get_ticklabels()[::2]:
    label.set_visible(False)
```


Question:
How to plot 2d math vectors with matplotlib? How can we plot 2D math vectors with matplotlib? Does anyone have an example or suggestion about that? I have a couple of vectors stored as 2D numpy arrays, and I would like to plot them as directed edges. The vectors to be plotted are constructed as below:
```
import numpy as np
# a list contains 3 vectors;
# each list is constructed as the tail and the head of the vector
a = np.array([[0, 0, 3, 2], [0, 0, 1, 1], [0, 0, 9, 9]])
```
Edit: I just added the plot of the final answer of tcaswell for anyone interested in the output and want to plot 2d vectors with matplotlib:

Response:
The suggestion in the comments by halex is correct, you want to use quiver (doc), but you need to tweak the properties a bit.
```
import numpy as np
import matplotlib.pyplot as plt

soa = np.array([[0, 0, 3, 2], [0, 0, 1, 1], [0, 0, 9, 9]])
X, Y, U, V = zip(*soa)
plt.figure()
ax = plt.gca()
ax.quiver(X, Y, U, V, angles='xy', scale_units='xy', scale=1)
ax.set_xlim([-1, 10])
ax.set_ylim([-1, 10])
plt.draw()
plt.show()
```


Question:
Rotate tick labels for seaborn barplot I am trying to display a chart with rotated x-axis labels, but the chart is not displaying.
```
import seaborn as sns
%matplotlib inline

yellow='#FFB11E'
by_school=sns.barplot(x ='Organization Name',y ='Score',data = combined.sort('Organization Name'),color=yellow,ci=None)
```
At this point I can see the image, but after I set the xticklabel, I don't see the image anymore only an object reference. (I would post the image, but I don't enough reputation :()
```
by_school.set_xticklabels('Organization Name',rotation=45)

<matplotlib.axes._subplots.AxesSubplot at 0x3971a6a0>
```
A similar question is posted here: Rotate label text in seaborn factorplot but the solution is not working.

Response:
You need a different method call, namely .set_rotation for each ticklables. Since you already have the ticklabels, just change their rotations:
```
for item in by_school.get_xticklabels():
    item.set_rotation(45)
```
barplot returns a matplotlib.axes object (as of seaborn 0.6.0), therefore you have to rotate the labels this way. In other cases, when the method returns a FacetGrid object, refer to Rotate label text in seaborn factorplot


Question: How to draw a rectangle over a specific region in a matplotlib graph I have a graph, computed from some data, drawn in matplotlib. I want to draw a rectangular region around the global maximum of this graph. I tried plt.axhspan, but the rectangle doesn't seem to appear when I call plt.show() So, how can a rectangular region be drawn onto a matplotlib graph? Thanks!

Response:
The most likely reason is that you used data units for the x arguments when calling axhspan. From the function's docs (my emphasis): y coords are in data units and x coords are in axes (relative 0-1) units. So any rectangle stretching left of 0 or right of 1 is simply drawn off-plot. An easy alternative might be to add a Rectangle to your axis (e.g., via plt.gca and add_patch); Rectangle uses data units for both dimensions. The following would add a grey rectangle with width & height of 1 centered on (2,3):
```py
from matplotlib.patches import Rectangle
import matplotlib.pyplot as plt

fig = plt.figure()
plt.xlim(0, 10)
plt.ylim(0, 12)

someX, someY = 2, 5
currentAxis = plt.gca()
currentAxis.add_patch(Rectangle((someX - .5, someY - .5), 4, 6, facecolor="grey"))
```
Without facecolor
```py
currentAxis.add_patch(Rectangle((someX - .5, someY - .5), 4, 6, facecolor="none", ec='k', lw=2))
```


Question:
Rotate theta=0 on matplotlib polar plot I have the following example code:
```
import numpy as np
import matplotlib.pyplot as plt
import random

data_theta = range(10,171,10)

data_theta_rad = []
for i in data_theta:
    data_theta_rad.append(float(i)*np.pi/180.0)

data_r = random.sample(range(70, 90), 17)

print data_theta
print data_r

ax = plt.subplot(111, polar=True)
ax.plot(data_theta_rad, data_r, color='r', linewidth=3)
ax.set_rmax(95)
# ax.set_rmin(70.0)
ax.grid(True)

ax.set_title("Example", va='bottom')
plt.show()
```
...which produces something like this: ...but I would like to set theta=0 to the 'West'. So something like: Any ideas how to do this with matplotlib (I made the pic below in powerpoint) ?

Response:
Simply use:
```
ax.set_theta_zero_location("W")
```
More info in the documentation of matplotlib.


Question:
Plot a black-and-white binary map in matplotlib I'm using python to simulate some automation models, and with the help of matplotlib I'm producing plots like the one shown below. I'm currently plotting with the following command:
```
ax.imshow(self.g, cmap=map, interpolation='nearest')
```
where self.g is the binary map (0 -> blue, 1 -> red in my current plots). However, to include this in my report I would like the plot to be with black dots on white background instead of red on blue. How do I accomplish that?

Response:
You can change the color map you are using via the cmap keyword. The color map 'Greys' provides the effect you want. You can find a list of available maps on the scipy website.
```
import matplotlib.pyplot as plt
import numpy as np

np.random.seed(101)
g = np.floor(np.random.random((100, 100)) + .5)

plt.subplot(211)
plt.imshow(g)
plt.subplot(212)
plt.imshow(g, cmap='Greys',  interpolation='nearest')
plt.savefig('blkwht.png')

plt.show()
```
which results in:


Question:
Python/Matplotlib - Colorbar Range and Display Values When using matplotlib with a contour plot, I'm having trouble getting the colorbar to display as I want. I've read through numerous similar examples, but have still not been able to get what I want. In the image below, I want two things changed. I want the minimum value and maximum values to be display on the color bar (the max should be 2.0 and the min -0.1). These two values should be at the very edge of the colorbar. Also, I want the colorbar to display the value at every color transition. For example. in the plot below, between 2.1 and 1.8, there is another color transition where the value isn't displayed. I think I may need to use norm, but it hasn't worked for me so far. Code:
```
import numpy as np
import matplotlib.pyplot as plt

xi = np.array([0., 0.5, 1.0])
yi = np.array([0., 0.5, 1.0])
zi = np.array([[0., 1.0, 2.0],
               [0., 1.0, 2.0],
               [-0.1, 1.0, 2.0]])

plt.contour(xi, yi, zi, 15, linewidths=0.5, colors='k')
plt.contourf(xi, yi, zi, 15, cmap=plt.cm.jet)
plt.colorbar()
plt.show()
```

Response:
If I understand correctly what you want, I think this should do it:
```
import numpy as np
import matplotlib.pyplot as plt

xi = np.array([0., 0.5, 1.0])
yi = np.array([0., 0.5, 1.0])
zi = np.array([[0., 1.0, 2.0],
               [0., 1.0, 2.0],
               [-0.1, 1.0, 2.0]])

v = np.linspace(-.1, 2.0, 15, endpoint=True)
plt.contour(xi, yi, zi, v, linewidths=0.5, colors='k')
plt.contourf(xi, yi, zi, v, cmap=plt.cm.jet)
x = plt.colorbar(ticks=v)
print x
plt.show()
```


Question: Difference between plt.close() and plt.clf() In matplotlib.pyplot, what is the difference between plt.clf() and plt.close()? Will they function the same way? I am running a loop where at the end of each iteration I am producing a figure and saving the plot. On first couple tries the plot was retaining the old figures in every subsequent plot. I'm looking for, individual plots for each iteration without the old figures, does it matter which one I use? The calculation I'm running takes a very long time and it would be very time consuming to test it out.

Response: plt.close() will close the figure window entirely, where plt.clf() will just clear the figure - you can still paint another plot onto it. It sounds like, for your needs, you should be preferring plt.clf(), or better yet keep a handle on the line objects themselves (they are returned in lists by plot calls) and use .set_data on those in subsequent iterations.


Question:
Cannot get minor grid lines to appear in matplotlib figure Ok so I have the code below for real-time graphing some data from an embedded device received over serial. It's not meant to be a production tool but rather an internal eng tool, hence it's not terribly user-friendly. The problem is that no matter what I do, I can't get minor grid lines to appear, even though here they are set to True, which=both. I can do anything I want to the major grid lines but the minors won't appear. Any ideas? Here is the code:
```
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation
import serial

SERIAL_PORT_NUM=9

...a bunch of constants...
#windows starts serial port numbers at 1, python starts at 0
SERIAL_PORT_NUM = SERIAL_PORT_NUM - 1
"""
Open the serial port
"""
ser =serial.Serial(port=SERIAL_PORT_NUM,baudrate=115200,bytesize=8,parity='N',stopbits=1,timeout=None,xonxoff=0,rtscts=0)

# First set up the figure, the axis, and the plot element we want to animate
raw_adc_fig = plt.figure()
raw_adc_ax = plt.axes(xlim=(0, 200), ylim=(0, 2047))
raw_adc_ax.grid(True, which='both')
raw_adc_fig.suptitle("Raw ADC data")
plt.ylabel("ADC values (hex)")
plt.xlabel("time (sec)")
raw_adc_line, = raw_adc_ax.plot([], [], lw=2)

def read_serial(serial_port):
    tmp = ''
    same_line = True
    while same_line:
        tmp += serial_port.read(1)
        if tmp != '':
            if tmp[-1] == '*':
                same_line = False
    tmp = tmp.rstrip()
    tmp = tmp.lstrip()
    return tmp

def process_serial(input_data):
    output_data = 0
    intermediate_data = input_data[A_TYPE_START_POS:A_TYPE_STOP_POS + 1]
    if( intermediate_data != ''):
        output_data =  int(intermediate_data , 16 )
    else:
        print "bad data"
        output_data = -100

    return output_data

def get_sound_value(serial_port):
    cur_line = ''

    get_next_line = True
    # read in the next line until a sound packet of type A is found
    while( get_next_line ):
        cur_line = read_serial(serial_port)
        if( (cur_line != '') and (cur_line[0:3] == ROUTER_SOUND_DATA) and (len(cur_line) == D_TYPE_STOP_POS + 2) ):
          get_next_line = False

    sound_value = process_serial(cur_line)
    return sound_value

# initialization function: plot the background of each frame
def raw_adc_init():
    raw_adc_line.set_data([], [])
    return raw_adc_line,

# animation function.  This is called sequentially
def raw_adc_animate(i):
    sound_data_list.append( get_sound_value(ser) )
    y = sound_data_list
    if( len(y) == 190 ):
        del y[0]
    x = np.linspace(0, len(y), len(y))
    raw_adc_line.set_data(x, y)
    return raw_adc_line,

# call the animator.  blit=True means only re-draw the parts that have changed.
raw_adc_anim = animation.FuncAnimation(raw_adc_fig, raw_adc_animate, init_func=raw_adc_init, frames=200, interval=1000, blit=True)
```
Edit: fixed a bug in opening the serial port. Changed timeout=0 to timeout=None.

Response: Unfortunately, ax.grid is a bit confusing in this regard. (This is a design bug / common gotcha.) It turns the minor grid on, but the minor ticks are still turned off. What you need to do is call plt.minorticks_on or ax.minorticks_on in addition to calling ax.grid(True, which='both').


Question:
Pandas DataFrame step plot: where="post" I am wondering how I can pass matplotlibs where="post" into a pandas plot.
```
import numpy as np
import pandas as pd

df = pd.DataFrame(np.random.randn(36, 3))
df.plot(drawstyle="steps", linewidth=2)

# this doesn't work
df.plot(drawstyle="steps", where='post')
```
Does anyone know how to realize this? Thanks in advance!

Response:
You just need to specify drawstyle="steps-post":
```
df = pd.DataFrame(np.random.randn(36, 3))
df.plot(drawstyle="steps", linewidth=2)
df.plot(drawstyle="steps-post", linewidth=2)
```
Compare the result:


Question: Increase distance between title and plot in matplolib? [duplicate] This question already has answers here: Python Matplotlib figure title overlaps axes label when using twiny (9 answers) Closed 6 years ago. I have a simple plot in matplotlib and I would like to increase the distance between the title and the plot (without using suptitle because it does not work on the version I use on a server). How to do that ?

Response:
With matplotlib 2.2+, you can use the keyword argument pad:
```
ax.set_title('Title', pad=20)
```
Adjust pad until you're happy with the axis title position. The advantage of this method over using rcParams is that it only changes this one axis title.