Question:
How do I set the figure title and axes labels font size? I am creating a figure in Matplotlib like this:
```py
from matplotlib import pyplot as plt

fig = plt.figure()
plt.plot(data)
fig.suptitle('test title')
plt.xlabel('xlabel')
plt.ylabel('ylabel')
fig.savefig('test.jpg')
```
I want to specify font sizes for the figure title and the axis labels. I need all three to be different font sizes, so setting a global font size (mpl.rcParams['font.size']=x) is not what I want. How do I set font sizes for the figure title and the axis labels individually?

Response:
Functions dealing with text like label, title, etc. accept parameters same as matplotlib.text.Text. For the font size you can use size/fontsize:
```
from matplotlib import pyplot as plt

fig = plt.figure()
plt.plot(data)
fig.suptitle('test title', fontsize=20)
plt.xlabel('xlabel', fontsize=18)
plt.ylabel('ylabel', fontsize=16)
fig.savefig('test.jpg')
```
For globally setting title and label sizes, mpl.rcParams contains axes.titlesize and axes.labelsize. (From the page):
```
axes.titlesize      : large   # fontsize of the axes title
axes.labelsize      : medium  # fontsize of the x any y labels
```
(As far as I can see, there is no way to set x and y label sizes separately.) And I see that axes.titlesize does not affect suptitle. I guess, you need to set that manually.


Question:
When to use cla(), clf() or close() for clearing a plot Matplotlib offers these functions:
```py
cla()   # Clear axis
clf()   # Clear figure
close() # Close a figure window
```
When should I use each function and what exactly does it do?

Response: They all do different things, since matplotlib uses a hierarchical order in which a figure window contains a figure which may consist of many axes. Additionally, there are functions from the pyplot interface and there are methods on the Figure class. I will discuss both cases below. pyplot interface pyplot is a module that collects a couple of functions that allow matplotlib to be used in a functional manner. I here assume that pyplot has been imported as import matplotlib.pyplot as plt. In this case, there are three different commands that remove stuff: See matplotlib.pyplot Functions: plt.cla() clears an axis, i.e. the currently active axis in the current figure. It leaves the other axes untouched. plt.clf() clears the entire current figure with all its axes, but leaves the window opened, such that it may be reused for other plots. plt.close() closes a window, which will be the current window, if not specified otherwise. Which functions suits you best depends thus on your use-case. The close() function furthermore allows one to specify which window should be closed. The argument can either be a number or name given to a window when it was created using figure(number_or_name) or it can be a figure instance fig obtained, i.e., usingfig = figure(). If no argument is given to close(), the currently active window will be closed. Furthermore, there is the syntax close('all'), which closes all figures. methods of the Figure class Additionally, the Figure class provides methods for clearing figures. I'll assume in the following that fig is an instance of a Figure: fig.clf() clears the entire figure. This call is equivalent to plt.clf() only if fig is the current figure. fig.clear() is a synonym for fig.clf() Note that even del fig will not close the associated figure window. As far as I know the only way to close a figure window is using plt.close(fig) as described above.


Question:
What does the argument mean in fig.add_subplot(111)? Sometimes I come across code such as this:
```
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [1, 4, 9, 16, 25]
fig = plt.figure()
fig.add_subplot(111)
plt.scatter(x, y)
plt.show()
```
Which produces: I've been reading the documentation like crazy but I can't find an explanation for the 111. sometimes I see a 212. What does the argument of fig.add_subplot() mean?

Response:
I think this would be best explained by the following picture: To initialize the above, one would type:
```
import matplotlib.pyplot as plt
fig = plt.figure()
fig.add_subplot(221)   #top left
fig.add_subplot(222)   #top right
fig.add_subplot(223)   #bottom left
fig.add_subplot(224)   #bottom right
plt.show()
```


Question: How to change the figure size of a seaborn axes or figure level plot How do I change the size of my image so it's suitable for printing? For example, I'd like to use an A4 paper, whose dimensions are 11.7 inches by 8.27 inches in landscape orientation.

Response:
You can also set figure size by passing dictionary to rc parameter with key 'figure.figsize' in seaborn set_theme method (which replaces the set method, deprecated in v0.11.0 (September 2020))
```
import seaborn as sns

sns.set_theme(rc={'figure.figsize':(11.7,8.27)})
```
Other alternative may be to use figure.figsize of rcParams to set figure size as below:
```
from matplotlib import rcParams

# figure size in inches
rcParams['figure.figsize'] = 11.7,8.27
```
More details can be found in matplotlib documentation


Question:
How to remove xticks from a plot I have a semilogx plot and I would like to remove the xticks. I tried:
```
plt.gca().set_xticks([])
plt.xticks([])
ax.set_xticks([])
```
The grid disappears (ok), but small ticks (at the place of the main ticks) remain. How to remove them?

Response:
The plt.tick_params method is very useful for stuff like this. This code turns off major and minor ticks and removes the labels from the x-axis. Note that there is also ax.tick_params for matplotlib.axes.Axes objects.
```
from matplotlib import pyplot as plt
plt.plot(range(10))
plt.tick_params(
    axis='x',          # changes apply to the x-axis
    which='both',      # both major and minor ticks are affected
    bottom=False,      # ticks along the bottom edge are off
    top=False,         # ticks along the top edge are off
    labelbottom=False) # labels along the bottom edge are off
plt.show()
plt.savefig('plot')
plt.clf()
```


Question: Matplotlib different size subplots I need to add two subplots to a figure. One subplot needs to be about three times as wide as the second (same height). I accomplished this using GridSpec and the colspan argument but I would like to do this using figure so I can save to PDF. I can adjust the first figure using the figsize argument in the constructor, but how do I change the size of the second plot?

Response:
As of matplotlib 3.6.0, width_ratios and height_ratios can now be passed directly as keyword arguments to plt.subplots and subplot_mosaic, as per What's new in Matplotlib 3.6.0 (Sep 15, 2022). f, (a0, a1) = plt.subplots(1, 2, width_ratios=[3, 1]) f, (a0, a1, a2) = plt.subplots(3, 1, height_ratios=[1, 1, 3]) Another way is to use the subplots function and pass the width ratio with gridspec_kw matplotlib Tutorial: Customizing Figure Layouts Using GridSpec and Other Functions matplotlib.gridspec.GridSpec has available gridspect_kw options
```py
import numpy as np
import matplotlib.pyplot as plt

# generate some data
x = np.arange(0, 10, 0.2)
y = np.sin(x)

# plot it
f, (a0, a1) = plt.subplots(1, 2, gridspec_kw={'width_ratios': [3, 1]})
a0.plot(x, y)
a1.plot(y, x)

f.tight_layout()
f.savefig('grid_figure.pdf')
```
Because the question is canonical, here is an example with vertical subplots.
```py
# plot it
f, (a0, a1, a2) = plt.subplots(3, 1, gridspec_kw={'height_ratios': [1, 1, 3]})

a0.plot(x, y)
a1.plot(x, y)
a2.plot(x, y)

f.tight_layout()
```


Question:
Display image as grayscale I'm trying to display a grayscale image using matplotlib.pyplot.imshow(). My problem is that the grayscale image is displayed as a colormap. I need it to be grayscale because I want to draw on top of the image with color. I read in the image and convert to grayscale using PIL's Image.open().convert("L")
```
image = Image.open(file).convert("L")
```
Then I convert the image to a matrix so that I can easily do some image processing using
```
matrix = scipy.misc.fromimage(image, 0)
```
However, when I do
```
figure()
matplotlib.pyplot.imshow(matrix)
show()
```
it displays the image using a colormap (i.e. it's not grayscale). What am I doing wrong here?

Response:
The following code will load an image from a file image.png and will display it as grayscale.
```
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image

fname = 'image.png'
image = Image.open(fname).convert("L")
arr = np.asarray(image)
plt.imshow(arr, cmap='gray', vmin=0, vmax=255)
plt.show()
```
If you want to display the inverse grayscale, switch the cmap to cmap='gray_r'.


Question:
How can I convert an RGB image into grayscale in Python? I'm trying to use matplotlib to read in an RGB image and convert it to grayscale. In matlab I use this:
```
img = rgb2gray(imread('image.png'));
```
In the matplotlib tutorial they don't cover it. They just read in the image
```
import matplotlib.image as mpimg
img = mpimg.imread('image.png')
```
and then they slice the array, but that's not the same thing as converting RGB to grayscale from what I understand.
```
lum_img = img[:,:,0]
```
I find it hard to believe that numpy or matplotlib doesn't have a built-in function to convert from rgb to gray. Isn't this a common operation in image processing? I wrote a very simple function that works with the image imported using imread in 5 minutes. It's horribly inefficient, but that's why I was hoping for a professional implementation built-in. Sebastian has improved my function, but I'm still hoping to find the built-in one. matlab's (NTSC/PAL) implementation:
```
import numpy as np

def rgb2gray(rgb):

    r, g, b = rgb[:,:,0], rgb[:,:,1], rgb[:,:,2]
    gray = 0.2989 * r + 0.5870 * g + 0.1140 * b

    return gray
```

Response:
How about doing it with Pillow:
```
from PIL import Image
img = Image.open('image.png').convert('L')
img.save('greyscale.png')
```
If an alpha (transparency) channel is present in the input image and should be preserved, use mode LA:
```
img = Image.open('image.png').convert('LA')
```
Using matplotlib and the formula
```
Y' = 0.2989 R + 0.5870 G + 0.1140 B
```
you could do:
```
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg

def rgb2gray(rgb):
    return np.dot(rgb[...,:3], [0.2989, 0.5870, 0.1140])

img = mpimg.imread('image.png')
gray = rgb2gray(img)
plt.imshow(gray, cmap=plt.get_cmap('gray'), vmin=0, vmax=1)
plt.show()
```


Question:
Is there a way to detach matplotlib plots so that the computation can continue? After these instructions in the Python interpreter one gets a window with a plot:
```
from matplotlib.pyplot import *
plot([1,2,3])
show()
# other code
```
Unfortunately, I don't know how to continue to interactively explore the figure created by show() while the program does further calculations. Is it possible at all? Sometimes calculations are long and it would help if they would proceed during examination of intermediate results.

Response:
Use matplotlib's calls that won't block: Using draw():
```
from matplotlib.pyplot import plot, draw, show
plot([1,2,3])
draw()
print('continue computation')

# at the end call show to ensure window won't close.
show()
```
Using interactive mode:
```
from matplotlib.pyplot import plot, ion, show
ion() # enables interactive mode
plot([1,2,3]) # result shows immediatelly (implicit draw())

print('continue computation')

# at the end call show to ensure window won't close.
show()
```


Question:
Rotate label text in seaborn I have a simple factorplot
```
import seaborn as sns
g = sns.factorplot("name", "miss_ratio", "policy", dodge=.2,
    linestyles=["none", "none", "none", "none"], data=df[df["level"] == 2])
```
The problem is that the x labels all run together, making them unreadable. How do you rotate the text so that the labels are readable?

Response:
I had a problem with the answer by @mwaskorn, namely that
```
g.set_xticklabels(rotation=30)
```
fails, because this also requires the labels. A bit easier than the answer by @Aman is to just add
```
plt.xticks(rotation=30)
```


Question: Set markers for individual points on a line I have used Matplotlib to plot lines on a figure. Now I would now like to set the style, specifically the marker, for individual points on the line. How do I do this? To clarify my question, I want to be able to set the style for individual markers on a line, not every marker on said line.

Response:
Specify the keyword args linestyle and/or marker in your call to plot. For example, using a dashed line and blue circle markers:
```
plt.plot(range(10), linestyle='--', marker='o', color='b', label='line with marker')
plt.legend()
```
A shortcut call for the same thing:
```
plt.plot(range(10), '--bo', label='line with marker')
plt.legend()
```
Here is a list of the possible line and marker styles:
```
================    ===============================
character           description
================    ===============================
   -                solid line style
   --               dashed line style
   -.               dash-dot line style
   :                dotted line style
   .                point marker
   ,                pixel marker
   o                circle marker
   v                triangle_down marker
   ^                triangle_up marker
   <                triangle_left marker
   >                triangle_right marker
   1                tri_down marker
   2                tri_up marker
   3                tri_left marker
   4                tri_right marker
   s                square marker
   p                pentagon marker
   *                star marker
   h                hexagon1 marker
   H                hexagon2 marker
   +                plus marker
   x                x marker
   D                diamond marker
   d                thin_diamond marker
   |                vline marker
   _                hline marker
================    ===============================
```
edit: with an example of marking an arbitrary subset of points, as requested in the comments:
```
import numpy as np
import matplotlib.pyplot as plt

xs = np.linspace(-np.pi, np.pi, 30)
ys = np.sin(xs)
markers_on = [12, 17, 18, 19]
plt.plot(xs, ys, '-gD', markevery=markers_on, label='line with select markers')
plt.legend()
plt.show()
```
This last example using the markevery kwarg is possible in since 1.4+, due to the merge of this feature branch. If you are stuck on an older version of matplotlib, you can still achieve the result by overlaying a scatterplot on the line plot. See the edit history for more details.


Question:
How to convert a NumPy array to PIL image applying matplotlib colormap I want to take a NumPy 2D array which represents a grayscale image, and convert it to an RGB PIL image while applying some of the matplotlib colormaps. I can get a reasonable PNG output by using the pyplot.figure.figimage command:
```
dpi = 100.0
w, h = myarray.shape[1]/dpi, myarray.shape[0]/dpi
fig = plt.figure(figsize=(w,h), dpi=dpi)
fig.figimage(sub, cmap=cm.gist_earth)
plt.savefig('out.png')
```
Although I could adapt this to get what I want (probably using StringIO do get the PIL image), I wonder if there is not a simpler way to do that, since it seems to be a very natural problem of image visualization. Let's say, something like this:
```
colored_PIL_image = magic_function(array, cmap)
```

Response:
Quite a busy one-liner, but here it is: First ensure your NumPy array, myarray, is normalised with the max value at 1.0. Apply the colormap directly to myarray. Rescale to the 0-255 range. Convert to integers, using np.uint8(). Use Image.fromarray(). And you're done:
```
from PIL import Image
from matplotlib import cm
im = Image.fromarray(np.uint8(cm.gist_earth(myarray)*255))
```
with plt.savefig(): with im.save():


Question:
Reduce left and right margins in matplotlib plot I'm struggling to deal with my plot margins in matplotlib. I've used the code below to produce my chart:
```
plt.imshow(g)
c = plt.colorbar()
c.set_label("Number of Slabs")
plt.savefig("OutputToUse.png")
```
However, I get an output figure with lots of white space on either side of the plot. I've searched google and read the matplotlib documentation, but I can't seem to find how to reduce this.

Response:
One way to automatically do this is the bbox_inches='tight' kwarg to plt.savefig. E.g.
```
import matplotlib.pyplot as plt
import numpy as np
data = np.arange(3000).reshape((100,30))
plt.imshow(data)
plt.savefig('test.png', bbox_inches='tight')
```
Another way is to use fig.tight_layout()
```
import matplotlib.pyplot as plt
import numpy as np

xs = np.linspace(0, 1, 20); ys = np.sin(xs)

fig = plt.figure()
axes = fig.add_subplot(1,1,1)
axes.plot(xs, ys)

# This should be called after all axes have been added
fig.tight_layout()
fig.savefig('test.png')
```


Question:
Getting individual colors from a color map in matplotlib If you have a Colormap cmap, for example:
```
cmap = matplotlib.cm.get_cmap('Spectral')
```
How can you get a particular colour out of it between 0 and 1, where 0 is the first colour in the map and 1 is the last colour in the map? Ideally, I would be able to get the middle colour in the map by doing:
```

```python
do_some_magic(cmap, 0.5) # Return an RGBA tuple
#Output
#(0.1, 0.2, 0.3, 1.0)
#```
```

Response:
You can do this with the code below, and the code in your question was actually very close to what you needed, all you have to do is call the cmap object you have.
```
import matplotlib

cmap = matplotlib.cm.get_cmap('Spectral')

rgba = cmap(0.5)
print(rgba) # (0.99807766255210428, 0.99923106502084169, 0.74602077638401709, 1.0)
```
For values outside of the range [0.0, 1.0] it will return the under and over colour (respectively). This, by default, is the minimum and maximum colour within the range (so 0.0 and 1.0). This default can be changed with cmap.set_under() and cmap.set_over(). For "special" numbers such as np.nan and np.inf the default is to use the 0.0 value, this can be changed using cmap.set_bad() similarly to under and over as above. Finally it may be necessary for you to normalize your data such that it conforms to the range [0.0, 1.0]. This can be done using matplotlib.colors.Normalize simply as shown in the small example below where the arguments vmin and vmax describe what numbers should be mapped to 0.0 and 1.0 respectively.
```
import matplotlib

norm = matplotlib.colors.Normalize(vmin=10.0, vmax=20.0)

print(norm(15.0)) # 0.5
```
A logarithmic normaliser (matplotlib.colors.LogNorm) is also available for data ranges with a large range of values. (Thanks to both Joe Kington and tcaswell for suggestions on how to improve the answer.)


Question: How to do a scatter plot with empty circles in Python? In Python, with Matplotlib, how can a scatter plot with empty circles be plotted? The goal is to draw empty circles around some of the colored disks already plotted by scatter(), so as to highlight them, ideally without having to redraw the colored circles. I tried facecolors=None, to no avail.

Response:
From the documentation for scatter:
```
Optional kwargs control the Collection properties; in particular:

    edgecolors:
        The string ‘none’ to plot faces with no outlines
    facecolors:
        The string ‘none’ to plot unfilled outlines
```
Try the following:
```
import matplotlib.pyplot as plt
import numpy as np

x = np.random.randn(60)
y = np.random.randn(60)

plt.scatter(x, y, s=80, facecolors='none', edgecolors='r')
plt.show()
```
Note: For other types of plots see this post on the use of markeredgecolor and markerfacecolor.


Question:
How to plot in multiple subplots I am a little confused about how this code works:
```
fig, axes = plt.subplots(nrows=2, ncols=2)
plt.show()
```
How does the fig, axes work in this case? What does it do? Also why wouldn't this work to do the same thing:
```
fig = plt.figure()
axes = fig.subplots(nrows=2, ncols=2)
```

Response:
There are several ways to do it. The subplots method creates the figure along with the subplots that are then stored in the ax array. For example:
```
import matplotlib.pyplot as plt

x = range(10)
y = range(10)

fig, ax = plt.subplots(nrows=2, ncols=2)

for row in ax:
    for col in row:
        col.plot(x, y)

plt.show()
```
However, something like this will also work, it's not so "clean" though since you are creating a figure with subplots and then add on top of them:
```
fig = plt.figure()

plt.subplot(2, 2, 1)
plt.plot(x, y)

plt.subplot(2, 2, 2)
plt.plot(x, y)

plt.subplot(2, 2, 3)
plt.plot(x, y)

plt.subplot(2, 2, 4)
plt.plot(x, y)

plt.show()
```


Question:
How to set xlim and ylim for a subplot [duplicate] This question already has answers here: How to set the subplot axis range (6 answers) Closed 10 years ago. I would like to limit the X and Y axis in matplotlib for a specific subplot. The subplot figure itself doesn't have any axis property. I want for example to change only the limits for the second plot:
```
import matplotlib.pyplot as plt
fig=plt.subplot(131)
plt.scatter([1,2],[3,4])
fig=plt.subplot(132)
plt.scatter([10,20],[30,40])
fig=plt.subplot(133)
plt.scatter([15,23],[35,43])
plt.show()
```

Response:
You should use the object-oriented interface to matplotlib, rather than the state machine interface. Almost all of the plt.* function are thin wrappers that basically do gca().*. plt.subplot returns an axes object. Once you have a reference to the axes object you can plot directly to it, change its limits, etc.
```
import matplotlib.pyplot as plt

ax1 = plt.subplot(131)
ax1.scatter([1, 2], [3, 4])
ax1.set_xlim([0, 5])
ax1.set_ylim([0, 5])

ax2 = plt.subplot(132)
ax2.scatter([1, 2],[3, 4])
ax2.set_xlim([0, 5])
ax2.set_ylim([0, 5])
```
and so on for as many axes as you want. Or better, wrap it all up in a loop:
```
import matplotlib.pyplot as plt

DATA_x = ([1, 2],
          [2, 3],
          [3, 4])

DATA_y = DATA_x[::-1]

XLIMS = [[0, 10]] * 3
YLIMS = [[0, 10]] * 3

for j, (x, y, xlim, ylim) in enumerate(zip(DATA_x, DATA_y, XLIMS, YLIMS)):
    ax = plt.subplot(1, 3, j + 1)
    ax.scatter(x, y)
    ax.set_xlim(xlim)
    ax.set_ylim(ylim)
```


Question:
Date ticks and rotation [duplicate] This question already has answers here: Rotate axis tick labels (13 answers) Closed 2 years ago. I am having an issue trying to get my date ticks rotated in matplotlib. A small sample program is below. If I try to rotate the ticks at the end, the ticks do not get rotated. If I try to rotate the ticks as shown under the comment 'crashes', then matplot lib crashes. This only happens if the x-values are dates. If I replaces the variable dates with the variable t in the call to avail_plot, the xticks(rotation=70) call works just fine inside avail_plot. Any ideas?
```
import numpy as np
import matplotlib.pyplot as plt
import datetime as dt

def avail_plot(ax, x, y, label, lcolor):
    ax.plot(x,y,'b')
    ax.set_ylabel(label, rotation='horizontal', color=lcolor)
    ax.get_yaxis().set_ticks([])

    #crashes
    #plt.xticks(rotation=70)

    ax2 = ax.twinx()
    ax2.plot(x, [1 for a in y], 'b')
    ax2.get_yaxis().set_ticks([])
    ax2.set_ylabel('testing')

f, axs = plt.subplots(2, sharex=True, sharey=True)
t = np.arange(0.01, 5, 1)
s1 = np.exp(t)
start = dt.datetime.now()
dates=[]
for val in t:
    next_val = start + dt.timedelta(0,val)
    dates.append(next_val)
    start = next_val

avail_plot(axs[0], dates, s1, 'testing', 'green')
avail_plot(axs[1], dates, s1, 'testing2', 'red')
plt.subplots_adjust(hspace=0, bottom=0.3)
plt.yticks([0.5,],("",""))
#doesn't crash, but does not rotate the xticks
#plt.xticks(rotation=70)
plt.show()
```

Response:
If you prefer a non-object-oriented approach, move plt.xticks(rotation=70) to right before the two avail_plot calls, eg
```
plt.xticks(rotation=70)
avail_plot(axs[0], dates, s1, 'testing', 'green')
avail_plot(axs[1], dates, s1, 'testing2', 'red')
```
This sets the rotation property before setting up the labels. Since you have two axes here, plt.xticks gets confused after you've made the two plots. At the point when plt.xticks doesn't do anything, plt.gca() does not give you the axes you want to modify, and so plt.xticks, which acts on the current axes, is not going to work. For an object-oriented approach not using plt.xticks, you can use
```
plt.setp( axs[1].xaxis.get_majorticklabels(), rotation=70 )
```
after the two avail_plot calls. This sets the rotation on the correct axes specifically.


Question:
Format y axis as percent I have an existing plot that was created with pandas like this:
```
df['myvar'].plot(kind='bar')
```
The y axis is format as float and I want to change the y axis to percentages. All of the solutions I found use ax.xyz syntax and I can only place code below the line above that creates the plot (I cannot add ax=ax to the line above.) How can I format the y axis as percentages without changing the line above? Here is the solution I found but requires that I redefine the plot:
```
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.ticker as mtick

data = [8,12,15,17,18,18.5]
perc = np.linspace(0,100,len(data))

fig = plt.figure(1, (7,4))
ax = fig.add_subplot(1,1,1)

ax.plot(perc, data)

fmt = '%.0f%%' # Format you want the ticks, e.g. '40%'
xticks = mtick.FormatStrFormatter(fmt)
ax.xaxis.set_major_formatter(xticks)

plt.show()
```
Link to the above solution: Pyplot: using percentage on x axis

Response:
This is a few months late, but I have created PR#6251 with matplotlib to add a new PercentFormatter class. With this class you just need one line to reformat your axis (two if you count the import of matplotlib.ticker):
```
import ...
import matplotlib.ticker as mtick

ax = df['myvar'].plot(kind='bar')
ax.yaxis.set_major_formatter(mtick.PercentFormatter())
```
PercentFormatter() accepts three arguments, xmax, decimals, symbol. xmax allows you to set the value that corresponds to 100% on the axis. This is nice if you have data from 0.0 to 1.0 and you want to display it from 0% to 100%. Just do PercentFormatter(1.0). The other two parameters allow you to set the number of digits after the decimal point and the symbol. They default to None and '%', respectively. decimals=None will automatically set the number of decimal points based on how much of the axes you are showing. Update PercentFormatter was introduced into Matplotlib proper in version 2.1.0.


Question:
reducing number of plot ticks I have too many ticks on my graph and they are running into each other. How can I reduce the number of ticks? For example, I have ticks:
```
1E-6, 1E-5, 1E-4, ... 1E6, 1E7
```
And I only want:
```
1E-5, 1E-3, ... 1E5, 1E7
```
I've tried playing with the LogLocator, but I haven't been able to figure this out.

Response:
Alternatively, if you want to simply set the number of ticks while allowing matplotlib to position them (currently only with MaxNLocator), there is pyplot.locator_params,
```
pyplot.locator_params(nbins=4)
```
You can specify specific axis in this method as mentioned below, default is both:
```
# To specify the number of ticks on both or any single axes
pyplot.locator_params(axis='y', nbins=6)
pyplot.locator_params(axis='x', nbins=10)
```


Question: How to plot multiple dataframes in subplots I have a few Pandas DataFrames sharing the same value scale, but having different columns and indices. When invoking df.plot(), I get separate plot images. what I really want is to have them all in the same plot as subplots, but I'm unfortunately failing to come up with a solution to how and would highly appreciate some help.

Response:
You can manually create the subplots with matplotlib, and then plot the dataframes on a specific subplot using the ax keyword. For example for 4 subplots (2x2):
```
import matplotlib.pyplot as plt

fig, axes = plt.subplots(nrows=2, ncols=2)

df1.plot(ax=axes[0,0])
df2.plot(ax=axes[0,1])
...
```
Here axes is an array which holds the different subplot axes, and you can access one just by indexing axes. If you want a shared x-axis, then you can provide sharex=True to plt.subplots.


Question:
How do I equalize the scales of the x-axis and y-axis? How do I create a plot where the scales of x-axis and y-axis are the same? This equal ratio should be maintained even if I change the window size. Currently, my graph scales together with the window size. I tried:
```
plt.xlim(-3, 3)
plt.ylim(-3, 3)
plt.axis('equal')
```

Response:
Use Axes.set_aspect in the following manner:
```
from matplotlib import pyplot as plt
plt.plot(range(5))
plt.xlim(-3, 3)
plt.ylim(-3, 3)
ax = plt.gca()
ax.set_aspect('equal', adjustable='box')
plt.draw()
```


Question:
Set Colorbar Range I have the following code:
```py
import matplotlib.pyplot as plt

cdict = {
  'red'  :  ( (0.0, 0.25, .25), (0.02, .59, .59), (1., 1., 1.)),
  'green':  ( (0.0, 0.0, 0.0), (0.02, .45, .45), (1., .97, .97)),
  'blue' :  ( (0.0, 1.0, 1.0), (0.02, .75, .75), (1., 0.45, 0.45))
}

cm = m.colors.LinearSegmentedColormap('my_colormap', cdict, 1024)

plt.clf()
plt.pcolor(X, Y, v, cmap=cm)
plt.loglog()
plt.xlabel('X Axis')
plt.ylabel('Y Axis')

plt.colorbar()
plt.show()
```
This produces a graph of the values v on the axes X vs Y, using the specified colormap. The X and Y axes are perfect, but the colormap spreads between the min and max of v. I would like to force the colormap to range between 0 and 1. I thought of using:
```py
plt.axis(...)
```
To set the ranges of the axes, but this only takes arguments for the min and max of X and Y, not the colormap. Edit: For clarity, let's say I have one graph whose values range (0 ... 0.3), and another graph whose values (0.2 ... 0.8). In both graphs, I will want the range of the colorbar to be (0 ... 1). In both graphs, I want this range of colour to be identical using the full range of cdict above (so 0.25 in both graphs will be the same colour). In the first graph, all colours between 0.3 and 1.0 won't feature in the graph, but will in the colourbar key at the side. In the other, all colours between 0 and 0.2, and between 0.8 and 1 will not feature in the graph, but will in the colourbar at the side.

Response:
Using vmin and vmax forces the range for the colors. Here's an example:
```
import matplotlib as m
import matplotlib.pyplot as plt
import numpy as np

cdict = {
  'red'  :  ( (0.0, 0.25, .25), (0.02, .59, .59), (1., 1., 1.)),
  'green':  ( (0.0, 0.0, 0.0), (0.02, .45, .45), (1., .97, .97)),
  'blue' :  ( (0.0, 1.0, 1.0), (0.02, .75, .75), (1., 0.45, 0.45))
}

cm = m.colors.LinearSegmentedColormap('my_colormap', cdict, 1024)

x = np.arange(0, 10, .1)
y = np.arange(0, 10, .1)
X, Y = np.meshgrid(x,y)

data = 2*( np.sin(X) + np.sin(3*Y) )

def do_plot(n, f, title):
    #plt.clf()
    plt.subplot(1, 3, n)
    plt.pcolor(X, Y, f(data), cmap=cm, vmin=-4, vmax=4)
    plt.title(title)
    plt.colorbar()

plt.figure()
do_plot(1, lambda x:x, "all")
do_plot(2, lambda x:np.clip(x, -4, 0), "<0")
do_plot(3, lambda x:np.clip(x, 0, 4), ">0")
plt.show()
```


Question:
How to put individual tags for a matplotlib scatter plot? I am trying to do a scatter plot in matplotlib and I couldn't find a way to add tags to the points. For example:
```
scatter1=plt.scatter(data1["x"], data1["y"], marker="o",
                     c="blue",
                     facecolors="white",
                     edgecolors="blue")
```
I want for the points in "y" to have labels as "point 1", "point 2", etc. I couldn't figure it out.

Response:
Perhaps use plt.annotate:
```
import numpy as np
import matplotlib.pyplot as plt

N = 10
data = np.random.random((N, 4))
labels = ['point{0}'.format(i) for i in range(N)]

plt.subplots_adjust(bottom = 0.1)
plt.scatter(
    data[:, 0], data[:, 1], marker='o', c=data[:, 2], s=data[:, 3] * 1500,
    cmap=plt.get_cmap('Spectral'))

for label, x, y in zip(labels, data[:, 0], data[:, 1]):
    plt.annotate(
        label,
        xy=(x, y), xytext=(-20, 20),
        textcoords='offset points', ha='right', va='bottom',
        bbox=dict(boxstyle='round,pad=0.5', fc='yellow', alpha=0.5),
        arrowprops=dict(arrowstyle = '->', connectionstyle='arc3,rad=0'))

plt.show()
```


Question: Plotting time on the independent axis I have an array of timestamps in the format (HH:MM:SS.mmmmmm) and another array of floating point numbers, each corresponding to a value in the timestamp array. Can I plot time on the x axis and the numbers on the y-axis using Matplotlib? I was trying to, but somehow it was only accepting arrays of floats. How can I get it to plot the time? Do I have to modify the format in any way?

Response:
Update: This answer is outdated since matplotlib version 3.5. The plot function now handles datetime data directly. See https://matplotlib.org/3.5.1/api/_as_gen/matplotlib.pyplot.plot_date.html The use of plot_date is discouraged. This method exists for historic reasons and may be deprecated in the future. datetime-like data should directly be plotted using plot. If you need to plot plain numeric data as Matplotlib date format or need to set a timezone, call ax.xaxis.axis_date / ax.yaxis.axis_date before plot. See Axis.axis_date. Old, outdated answer: You must first convert your timestamps to Python datetime objects (use datetime.strptime). Then use date2num to convert the dates to matplotlib format. Plot the dates and values using plot_date:
```
import matplotlib.pyplot as plt
import matplotlib.dates

from datetime import datetime

x_values = [datetime(2021, 11, 18, 12), datetime(2021, 11, 18, 14), datetime(2021, 11, 18, 16)]
y_values = [1.0, 3.0, 2.0]

dates = matplotlib.dates.date2num(x_values)
plt.plot_date(dates, y_values)
```


Question:
How do I tell matplotlib that I am done with a plot? The following code plots to two PostScript (.ps) files, but the second one contains both lines.
```
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab

plt.subplot(111)
x = [1,10]
y = [30, 1000]
plt.loglog(x, y, basex=10, basey=10, ls="-")
plt.savefig("first.ps")

plt.subplot(111)
x = [10,100]
y = [10, 10000]
plt.loglog(x, y, basex=10, basey=10, ls="-")
plt.savefig("second.ps")
```
How can I tell matplotlib to start afresh for the second plot?

Response:
There is a clear figure command, and it should do it for you:
```
plt.clf()
```
If you have multiple subplots in the same figure
```
plt.cla()
```
clears the current axes.


Question:
How do I create a second (new) plot, then later plot on the old one? I want to plot data, then create a new figure and plot data2, and finally come back to the original plot and plot data3, kinda like this:
```
import numpy as np
import matplotlib as plt

x = arange(5)
y = np.exp(5)
plt.figure()
plt.plot(x, y)

z = np.sin(x)
plt.figure()
plt.plot(x, z)

w = np.cos(x)
plt.figure("""first figure""") # Here's the part I need
plt.plot(x, w)
```
FYI How do I tell matplotlib that I am done with a plot? does something similar, but not quite! It doesn't let me get access to that original plot.

Response:
If you find yourself doing things like this regularly it may be worth investigating the object-oriented interface to matplotlib. In your case:
```
import matplotlib.pyplot as plt
import numpy as np

x = np.arange(5)
y = np.exp(x)
fig1, ax1 = plt.subplots()
ax1.plot(x, y)
ax1.set_title("Axis 1 title")
ax1.set_xlabel("X-label for axis 1")

z = np.sin(x)
fig2, (ax2, ax3) = plt.subplots(nrows=2, ncols=1) # two axes on figure
ax2.plot(x, z)
ax3.plot(x, -z)

w = np.cos(x)
ax1.plot(x, w) # can continue plotting on the first axis
```
It is a little more verbose but it's much clearer and easier to keep track of, especially with several figures each with multiple subplots.


Question:
How to plot a high resolution graph I've used matplotlib for plotting some experimental results (discussed it in here: Looping over files and plotting. However, saving the picture by clicking right to the image gives very bad quality / low resolution images.
```
from glob import glob
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl

# loop over all files in the current directory ending with .txt
for fname in glob("./*.txt"):
    # read file, skip header (1 line) and unpack into 3 variables
    WL, ABS, T = np.genfromtxt(fname, skip_header=1, unpack=True)

    # first plot
    plt.plot(WL, T, label='BN', color='blue')

    plt.xlabel('Wavelength (nm)')
    plt.xlim(200,1000)
    plt.ylim(0,100)
    plt.ylabel('Transmittance, %')
    mpl.rcParams.update({'font.size': 14})
    #plt.legend(loc='lower center')
    plt.title('')
    plt.show()
    plt.clf()

    # second plot
    plt.plot(WL, ABS, label='BN', color='red')
    plt.xlabel('Wavelength (nm)')
    plt.xlim(200,1000)
    plt.ylabel('Absorbance, A')
    mpl.rcParams.update({'font.size': 14})
    #plt.legend()
    plt.title('')
    plt.show()
    plt.clf()
```
Example graph of what I'm looking for: example graph

Response:
You can use savefig() to export to an image file:
```
plt.savefig('filename.png')
```
In addition, you can specify the dpi argument to some scalar value (default is 100). For example:
```
plt.savefig('filename.png', dpi=300)
```


Question:
How to display an image I tried to use IPython.display with the following code:
```
from IPython.display import display, Image
display(Image(filename='MyImage.png'))
```
I also tried to use matplotlib with the following code:
```
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
plt.imshow(mpimg.imread('MyImage.png'))
```
In both cases, nothing is displayed, not even an error message.

Response:
If you are using matplotlib and want to show the image in your interactive notebook, try the following:
```
%matplotlib inline
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
img = mpimg.imread('your_image.png')
imgplot = plt.imshow(img)
plt.show()
```


Question:
Plotting a list of (x, y) coordinates I have a list of pairs (a, b) that I would like to plot with matplotlib in python as actual x-y coordinates. Currently, it is making two plots, where the index of the list gives the x-coordinate, and the first plot's y values are the as in the pairs and the second plot's y values are the bs in the pairs. To clarify, my data looks like this: li = [(a,b), (c,d), ... , (t, u)] and I want to do a one-liner that just calls plt.plot(). If I didn't require a one-liner I could trivially do:
```py
xs = [x[0] for x in li]
ys = [x[1] for x in li]
plt.plot(xs, ys)
```
How can I get matplotlib to plot these pairs as x-y coordinates? Sample data
```py
# sample data
li = list(zip(range(1, 14), range(14, 27)))

li → [(1, 14), (2, 15), (3, 16), (4, 17), (5, 18), (6, 19), (7, 20), (8, 21), (9, 22), (10, 23), (11, 24), (12, 25), (13, 26)]
```
Incorrect Plot
```py
plt.plot(li)
plt.title('Incorrect Plot:\nEach index of the tuple plotted as separate lines')
```
Desired Plot This produces the correct plot, but to many lines of code are used to unpack li. I need to unpack and plot with a single line of code, not multiple list-comprehensions.
```py
xs = [x[0] for x in li]
ys = [x[1] for x in li]
plt.plot(xs, ys)
plt.title('Correct Plot:\nBut uses to many lines to unpack li')
```

Response:
Given li in the question:
```
li = list(zip(range(1, 14), range(14, 27)))
```
To unpack the data from pairs into lists use zip:
```
x, y = zip(*li)

x → (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)
y → (14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26)
```
The one-liner uses the unpacking operator (*), to unpack the list of tuples for zip, and unpacks the zip object into the plot API.
```
plt.scatter(*zip(*li))
```
```
plt.plot(*zip(*li))
```


Question:
Plt.show shows full graph but savefig is cropping the image My code is succesfully saving images to file, but it is cropping important details from the right hand side. Answers exist for fixing this problem when it arises for plt.show, but it is the savefig command that is incorrectly producing the graph in this example. How can this be fixed? The relevant sample of my code:
```
import glob
import os
for file in glob.glob("*.oax"):
    try:
        spc_file = open(file, 'r').read()
        newName = file[6:8] + '-' + file[4:6] + '-' + file[0:4] + ' ' + file[8:12] +  ' UTC (Observed) - No Sea Breeze Day'
        plt.title(newName, fontsize=12, loc='left')
        plt.savefig('X:/' + newName + '.png')
        plt.show()
    except Exception:
        pass
```
And the images (top is plt.show and bottom is file produced from savefig:

Response:
You may try
```
plt.savefig('X:/' + newName + '.png', bbox_inches='tight')
```
Or you may define figure size like
```
fig = plt.figure(figsize=(9, 11))
...
plt.savefig(filename, bbox_inches = 'tight')
```


Question:
How to rotate x-axis tick labels in a pandas plot With the following code:
```
import matplotlib
matplotlib.style.use('ggplot')
import matplotlib.pyplot as plt
import pandas as pd

df = pd.DataFrame({ 'celltype':["foo","bar","qux","woz"], 's1':[5,9,1,7], 's2':[12,90,13,87]})
df = df[["celltype","s1","s2"]]
df.set_index(["celltype"],inplace=True)
df.plot(kind='bar',alpha=0.75)
plt.xlabel("")
```
I made this plot: How can I rotate the x-axis tick labels to 0 degrees? I tried adding this but did not work:
```
plt.set_xticklabels(df.index,rotation=90)
```

Response:
Pass param rot=0 to rotate the xticklabels:
```
import matplotlib
matplotlib.style.use('ggplot')
import matplotlib.pyplot as plt
import pandas as pd

df = pd.DataFrame({ 'celltype':["foo","bar","qux","woz"], 's1':[5,9,1,7], 's2':[12,90,13,87]})
df = df[["celltype","s1","s2"]]
df.set_index(["celltype"],inplace=True)
df.plot(kind='bar',alpha=0.75, rot=0)
plt.xlabel("")
plt.show()
```
yields plot:


Question: Remove or adapt border of frame of legend using matplotlib When plotting a plot using matplotlib: How to remove the box of the legend? How to change the color of the border of the legend box? How to remove only the border of the box of the legend?

Response:
When plotting a plot using matplotlib: How to remove the box of the legend?
```
plt.legend(frameon=False)
```
How to change the color of the border of the legend box?
```
leg = plt.legend()
leg.get_frame().set_edgecolor('b')
```
How to remove only the border of the box of the legend?
```
leg = plt.legend()
leg.get_frame().set_linewidth(0.0)
```
For the matplotlib object oriented approach:
```
axes.legend(frameon=False)

leg = axes.legend()
leg.get_frame().set_edgecolor('b')
leg.get_frame().set_linewidth(0.0)
```


Question:
How to pick a new color for each plotted line within a figure I'd like to NOT specify a color for each plotted line, and have each line get a distinct color. But if I run:
```
from matplotlib import pyplot as plt
for i in range(20):
    plt.plot([0, 1], [i, i])

plt.show()
```
then I get this output: If you look at the image above, you can see that matplotlib attempts to pick colors for each line that are different, but eventually it re-uses colors - the top ten lines use the same colors as the bottom ten. I just want to stop it from repeating already used colors AND/OR feed it a list of colors to use.

Response:
I usually use the second one of these:
```py
from matplotlib.pyplot import cm
import numpy as np

#variable n below should be number of curves to plot

#version 1:

color = cm.rainbow(np.linspace(0, 1, n))
for i, c in enumerate(color):
   plt.plot(x, y, c=c)

#or version 2:

color = iter(cm.rainbow(np.linspace(0, 1, n)))
for i in range(n):
   c = next(color)
   plt.plot(x, y, c=c)
```
Example of 2:


Question:
How to share x axes of two subplots after they have been created I'm trying to share two subplots axes, but I need to share the x axis after the figure was created. E.g. I create this figure:
```py
import numpy as np
import matplotlib.pyplot as plt

t = np.arange(1000)/100.
x = np.sin(2*np.pi*10*t)
y = np.cos(2*np.pi*10*t)

fig = plt.figure()
ax1 = plt.subplot(211)
plt.plot(t,x)
ax2 = plt.subplot(212)
plt.plot(t,y)

# some code to share both x axes

plt.show()
```
Instead of the comment I want to insert some code to share both x axes. How do I do this? There are some relevant sounding attributes _shared_x_axes and _shared_x_axes when I check to figure axis (fig.get_axes()) but I don't know how to link them.

Response:
The usual way to share axes is to create the shared properties at creation. Either
```
fig=plt.figure()
ax1 = plt.subplot(211)
ax2 = plt.subplot(212, sharex = ax1)
```
or
```
fig, (ax1, ax2) = plt.subplots(nrows=2, sharex=True)
```
Sharing the axes after they have been created should therefore not be necessary. However if for any reason, you need to share axes after they have been created (actually, using a different library which creates some subplots, like here might be a reason), there would still be a solution: Using
```
ax2.sharex(ax1)
```
creates a link between the two axes, ax1 and ax2. In contrast to the sharing at creation time, you will have to set the xticklabels off manually for one of the axes (in case that is wanted). A complete example:
```
import numpy as np
import matplotlib.pyplot as plt

t= np.arange(1000)/100.
x = np.sin(2*np.pi*10*t)
y = np.cos(2*np.pi*10*t)

fig=plt.figure()
ax1 = plt.subplot(211)
ax2 = plt.subplot(212)

ax1.plot(t,x)
ax2.plot(t,y)

ax2.sharex(ax1)
ax1.set_xticklabels([])
# ax2.autoscale() ## call autoscale if needed

plt.show()
```
For a list of axes you would do:
```
for ax in axes[1:]:
    ax.sharex(axes[0])
```


Question:
How to connect scatterplot points with line using matplotlib I have two lists, dates and values. I want to plot them using matplotlib. The following creates a scatter plot of my data.
```py
import matplotlib.pyplot as plt

plt.scatter(dates,values)
plt.show()
```
plt.plot(dates, values) creates a line graph. But what I really want is a scatterplot where the points are connected by a line. Similar to in R:
```r
plot(dates, values)
lines(dates, value, type="l")
```
which gives me a scatterplot of points overlaid with a line connecting the points. How do I do this in python?

Response:
I think @Evert has the right answer:
```
plt.scatter(dates,values)
plt.plot(dates, values)
plt.show()
```
Which is pretty much the same as
```
plt.plot(dates, values, '-o')
plt.show()
```
You can replace -o with another suitable format string as described in the documentation. You can also split the choices of line and marker styles using the linestyle= and marker= keyword arguments.


Question:
How to plot multiple functions on the same figure How can I plot the following 3 functions (i.e. sin, cos and the addition), on the domain t, in the same figure?
```py
import numpy as np
import matplotlib.pyplot as plt

t = np.linspace(0, 2*np.pi, 400)

a = np.sin(t)
b = np.cos(t)
c = a + b
```

Response:
To plot multiple graphs on the same figure you will have to do:
```
from numpy import *
import math
import matplotlib.pyplot as plt

t = linspace(0, 2*math.pi, 400)
a = sin(t)
b = cos(t)
c = a + b

plt.plot(t, a, 'r') # plotting t, a separately
plt.plot(t, b, 'b') # plotting t, b separately
plt.plot(t, c, 'g') # plotting t, c separately
plt.show()
```


Question:
Moving x-axis to the top of a plot in matplotlib Based on this question about heatmaps in matplotlib, I wanted to move the x-axis titles to the top of the plot.
```
import matplotlib.pyplot as plt
import numpy as np
column_labels = list('ABCD')
row_labels = list('WXYZ')
data = np.random.rand(4,4)
fig, ax = plt.subplots()
heatmap = ax.pcolor(data, cmap=plt.cm.Blues)

# put the major ticks at the middle of each cell
ax.set_xticks(np.arange(data.shape[0])+0.5, minor=False)
ax.set_yticks(np.arange(data.shape[1])+0.5, minor=False)

# want a more natural, table-like display
ax.invert_yaxis()
ax.xaxis.set_label_position('top') # <-- This doesn't work!

ax.set_xticklabels(row_labels, minor=False)
ax.set_yticklabels(column_labels, minor=False)
plt.show()
```
However, calling matplotlib's set_label_position (as notated above) doesn't seem to have the desired effect. Here's my output: What am I doing wrong?

Response:
Use
```
ax.xaxis.tick_top()
```
to place the tick marks at the top of the image. The command
```
ax.set_xlabel('X LABEL')
ax.xaxis.set_label_position('top')
```
affects the label, not the tick marks.
```
import matplotlib.pyplot as plt
import numpy as np
column_labels = list('ABCD')
row_labels = list('WXYZ')
data = np.random.rand(4, 4)
fig, ax = plt.subplots()
heatmap = ax.pcolor(data, cmap=plt.cm.Blues)

# put the major ticks at the middle of each cell
ax.set_xticks(np.arange(data.shape[1]) + 0.5, minor=False)
ax.set_yticks(np.arange(data.shape[0]) + 0.5, minor=False)

# want a more natural, table-like display
ax.invert_yaxis()
ax.xaxis.tick_top()

ax.set_xticklabels(column_labels, minor=False)
ax.set_yticklabels(row_labels, minor=False)
plt.show()
```


Question:
Prevent scientific notation I have the following code:
```
plt.plot(range(2003,2012,1),range(200300,201200,100))
# several solutions from other questions have not worked, including
# plt.ticklabel_format(style='sci', axis='x', scilimits=(-1000000,1000000))
# ax.get_xaxis().get_major_formatter().set_useOffset(False)
plt.show()
```
which produces the following plot: How do I prevent scientific notation here? Is ticklabel_format broken? does not resolve the issue of actually removing the offset.
```py
plt.plot(np.arange(1e6, 3 * 1e7, 1e6))
plt.ticklabel_format(useOffset=False)
```

Response:
In your case, you're actually wanting to disable the offset. Using scientific notation is a separate setting from showing things in terms of an offset value. However, ax.ticklabel_format(useOffset=False) should have worked (though you've listed it as one of the things that didn't). For example:
```
fig, ax = plt.subplots()
ax.plot(range(2003,2012,1),range(200300,201200,100))
ax.ticklabel_format(useOffset=False)
plt.show()
```
If you want to disable both the offset and scientific notaion, you'd use ax.ticklabel_format(useOffset=False, style='plain'). Difference between "offset" and "scientific notation" In matplotlib axis formatting, "scientific notation" refers to a multiplier for the numbers show, while the "offset" is a separate term that is added. Consider this example:
```
import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(1000, 1001, 100)
y = np.linspace(1e-9, 1e9, 100)

fig, ax = plt.subplots()
ax.plot(x, y)
plt.show()
```
The x-axis will have an offset (note the + sign) and the y-axis will use scientific notation (as a multiplier -- No plus sign). We can disable either one separately. The most convenient way is the ax.ticklabel_format method (or plt.ticklabel_format). For example, if we call:
```
ax.ticklabel_format(style='plain')
```
We'll disable the scientific notation on the y-axis: And if we call
```
ax.ticklabel_format(useOffset=False)
```
We'll disable the offset on the x-axis, but leave the y-axis scientific notation untouched: Finally, we can disable both through:
```
ax.ticklabel_format(useOffset=False, style='plain')
```


Question:
How to maximize a plt.show() window Just for curiosity I would like to know how to do this in the code below. I have been searching for an answer but is useless.
```
import numpy as np
import matplotlib.pyplot as plt
data=np.random.exponential(scale=180, size=10000)
print ('el valor medio de la distribucion exponencial es: ')
print np.average(data)
plt.hist(data,bins=len(data)**0.5,normed=True, cumulative=True, facecolor='red', label='datos tamano paqutes acumulativa', alpha=0.5)
plt.legend()
plt.xlabel('algo')
plt.ylabel('algo')
plt.grid()
plt.show()
```

Response:
I am on a Windows (WIN7), running Python 2.7.5 & Matplotlib 1.3.1. I was able to maximize Figure windows for TkAgg, QT4Agg, and wxAgg using the following lines:
```py
from matplotlib import pyplot as plt

### for 'TkAgg' backend
plt.figure(1)
plt.switch_backend('TkAgg') #TkAgg (instead Qt4Agg)
print '#1 Backend:',plt.get_backend()
plt.plot([1,2,6,4])
mng = plt.get_current_fig_manager()
### works on Ubuntu??? >> did NOT working on windows
# mng.resize(*mng.window.maxsize())
mng.window.state('zoomed') #works fine on Windows!
plt.show() #close the figure to run the next section

### for 'wxAgg' backend
plt.figure(2)
plt.switch_backend('wxAgg')
print '#2 Backend:',plt.get_backend()
plt.plot([1,2,6,4])
mng = plt.get_current_fig_manager()
mng.frame.Maximize(True)
plt.show() #close the figure to run the next section

### for 'Qt4Agg' backend
plt.figure(3)
plt.switch_backend('QT4Agg') #default on my system
print '#3 Backend:',plt.get_backend()
plt.plot([1,2,6,4])
figManager = plt.get_current_fig_manager()
figManager.window.showMaximized()
plt.show()
```
if you want to maximize multiple figures you can use
```
for fig in figs:
    mng = fig.canvas.manager
    # ...
```
Hope this summary of the previous answers (and some additions) combined in a working example (at least for windows) helps.


Question:
How to create major and minor gridlines with different linestyles I am currently using matplotlib.pyplot to create graphs and would like to have the major gridlines solid and black and the minor ones either greyed or dashed. In the grid properties, which=both/major/mine, and then color and linestyle are defined simply by linestyle. Is there a way to specify minor linestyle only? The appropriate code I have so far is
```
plt.plot(current, counts, 'rd', markersize=8)
plt.yscale('log')
plt.grid(b=True, which='both', color='0.65', linestyle='-')
```

Response:
Actually, it is as simple as setting major and minor separately:
```

```python
plot([23, 456, 676, 89, 906, 34, 2345])
#Output
#[<matplotlib.lines.Line2D at 0x6112f90>]
```

```python
yscale('log')
```

```python
grid(visible=True, which='major', color='b', linestyle='-')
```

```python
grid(visible=True, which='minor', color='r', linestyle='--')
```
The gotcha with minor grids is that you have to have minor tick marks turned on too. In the above code this is done by yscale('log'), but it can also be done with plt.minorticks_on(). Note: before matplotlib 3.5, visible parameter was named b
```


Question:
Adding an arbitrary line to a matplotlib plot in ipython notebook I'm rather new to both python/matplotlib and using it through the ipython notebook. I'm trying to add some annotation lines to an existing graph and I can't figure out how to render the lines on a graph. So, for example, if I plot the following:
```
import numpy as np
np.random.seed(5)
x = arange(1, 101)
y = 20 + 3 * x + np.random.normal(0, 60, 100)
p =  plot(x, y, "o")
```
I get the following graph: So how would I add a vertical line from (70,100) up to (70,250)? What about a diagonal line from (70,100) to (90,200)? I've tried a few things with Line2D() resulting in nothing but confusion on my part. In R I would simply use the segments() function which would add line segments. Is there an equivalent in matplotlib?

Response:
You can directly plot the lines you want by feeding the plot command with the corresponding data (boundaries of the segments): plot([x1, x2], [y1, y2], color='k', linestyle='-', linewidth=2) (of course you can choose the color, line width, line style, etc.) From your example:
```
import numpy as np
import matplotlib.pyplot as plt

np.random.seed(5)
x = np.arange(1, 101)
y = 20 + 3 * x + np.random.normal(0, 60, 100)
plt.plot(x, y, "o")

# draw vertical line from (70,100) to (70, 250)
plt.plot([70, 70], [100, 250], 'k-', lw=2)

# draw diagonal line from (70, 90) to (90, 200)
plt.plot([70, 90], [90, 200], 'k-')

plt.show()
```


Question:
How to display multiple images in one figure [duplicate] This question already has answers here: Multiple figures in a single window (7 answers) Closed 7 years ago. I am trying to display 20 random images on a single Figure. The images are indeed displayed, but they are overlaid. I am using:
```
import numpy as np
import matplotlib.pyplot as plt
w=10
h=10
fig=plt.figure()
for i in range(1,20):
    img = np.random.randint(10, size=(h,w))
    fig.add_subplot(i,2,1)
    plt.imshow(img)
plt.show()
```
I would like them to appear naturally in a grid layout (say 4x5), each with the same size. Part of the problem is that I do not know what the arguments to add_subplot mean. The documentation states that the arguments are the number of rows, number of columns, and plot number. There is no positioning argument. Additionally, the plot number can only be 1 or 2. How can I achieve this?

Response:
Here is my approach that you may try:
```
import numpy as np
import matplotlib.pyplot as plt

w = 10
h = 10
fig = plt.figure(figsize=(8, 8))
columns = 4
rows = 5
for i in range(1, columns*rows +1):
    img = np.random.randint(10, size=(h,w))
    fig.add_subplot(rows, columns, i)
    plt.imshow(img)
plt.show()
```
The resulting image: (Original answer date: Oct 7 '17 at 4:20) Edit 1 Since this answer is popular beyond my expectation. And I see that a small change is needed to enable flexibility for the manipulation of the individual plots. So that I offer this new version to the original code. In essence, it provides:- access to individual axes of subplots possibility to plot more features on selected axes/subplot New code:
```
import numpy as np
import matplotlib.pyplot as plt

w = 10
h = 10
fig = plt.figure(figsize=(9, 13))
columns = 4
rows = 5

# prep (x,y) for extra plotting
xs = np.linspace(0, 2*np.pi, 60)  # from 0 to 2pi
ys = np.abs(np.sin(xs))           # absolute of sine

# ax enables access to manipulate each of subplots
ax = []

for i in range(columns*rows):
    img = np.random.randint(10, size=(h,w))
    # create subplot and append to ax
    ax.append( fig.add_subplot(rows, columns, i+1) )
    ax[-1].set_title("ax:"+str(i))  # set title
    plt.imshow(img, alpha=0.25)

# do extra plots on selected axes/subplots
# note: index starts with 0
ax[2].plot(xs, 3*ys)
ax[19].plot(ys**2, xs)

plt.show()  # finally, render the plot
```
The resulting plot: Edit 2 In the previous example, the code provides access to the sub-plots with single index, which is inconvenient when the figure has many rows/columns of sub-plots. Here is an alternative of it. The code below provides access to the sub-plots with [row_index][column_index], which is more suitable for manipulation of array of many sub-plots.
```
import matplotlib.pyplot as plt
import numpy as np

# settings
h, w = 10, 10        # for raster image
nrows, ncols = 5, 4  # array of sub-plots
figsize = [6, 8]     # figure size, inches

# prep (x,y) for extra plotting on selected sub-plots
xs = np.linspace(0, 2*np.pi, 60)  # from 0 to 2pi
ys = np.abs(np.sin(xs))           # absolute of sine

# create figure (fig), and array of axes (ax)
fig, ax = plt.subplots(nrows=nrows, ncols=ncols, figsize=figsize)

# plot simple raster image on each sub-plot
for i, axi in enumerate(ax.flat):
    # i runs from 0 to (nrows*ncols-1)
    # axi is equivalent with ax[rowid][colid]
    img = np.random.randint(10, size=(h,w))
    axi.imshow(img, alpha=0.25)
    # get indices of row/column
    rowid = i // ncols
    colid = i % ncols
    # write row/col indices as axes' title for identification
    axi.set_title("Row:"+str(rowid)+", Col:"+str(colid))

# one can access the axes by ax[row_id][col_id]
# do additional plotting on ax[row_id][col_id] of your choice
ax[0][2].plot(xs, 3*ys, color='red', linewidth=3)
ax[4][3].plot(ys**2, xs, color='green', linewidth=3)

plt.tight_layout(True)
plt.show()
```
The resulting plot: Ticks and Tick-labels for Array of Subplots Some of the ticks and tick-labels accompanying the subplots can be hidden to get cleaner plot if all of the subplots share the same value ranges. All of the ticks and tick-labels can be hidden except for the outside edges on the left and bottom like this plot. To achieve the plot with only shared tick-labels on the left and bottom edges, you can do the following:- Add options sharex=True, sharey=True in fig, ax = plt.subplots() That line of code will become:
```
fig,ax=plt.subplots(nrows=nrows,ncols=ncols,figsize=figsize,sharex=True,sharey=True)
```
To specify required number of ticks, and labels to plot, inside the body of for i, axi in enumerate(ax.flat):, add these code
```
axi.xaxis.set_major_locator(plt.MaxNLocator(5))
axi.yaxis.set_major_locator(plt.MaxNLocator(4))
```
the number 5, and 4 are the number of ticks/tick_labels to plot. You may need other values that suit your plots.


Question:
Can Pandas plot a histogram of dates? I've taken my Series and coerced it to a datetime column of dtype=datetime64[ns] (though only need day resolution...not sure how to change).
```
import pandas as pd
df = pd.read_csv('somefile.csv')
column = df['date']
column = pd.to_datetime(column, coerce=True)
```
but plotting doesn't work:
```
ipdb> column.plot(kind='hist')
*** TypeError: ufunc add cannot use operands with types dtype('<M8[ns]') and dtype('float64')
```
I'd like to plot a histogram that just shows the count of dates by week, month, or year. Surely there is a way to do this in pandas?

Response:
Given this df:
```
date
0 2001-08-10
1 2002-08-31
2 2003-08-29
3 2006-06-21
4 2002-03-27
5 2003-07-14
6 2004-06-15
7 2003-08-14
8 2003-07-29
```
and, if it's not already the case:
```
df["date"] = df["date"].astype("datetime64")
```
To show the count of dates by month:
```
df.groupby(df["date"].dt.month).count().plot(kind="bar")
```
.dt allows you to access the datetime properties. Which will give you: You can replace month by year, day, etc.. If you want to distinguish year and month for instance, just do:
```
df.groupby([df["date"].dt.year, df["date"].dt.month]).count().plot(kind="bar")
```
Which gives:


Question:
Pandas plot doesn't show When using this in a script (not IPython), nothing happens, i.e. the plot window doesn't appear :
```
import numpy as np
import pandas as pd
ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000))
ts.plot()
```
Even when adding time.sleep(5), there is still nothing. Why? Is there a way to do it, without having to manually call matplotlib ?

Response:
Once you have made your plot, you need to tell matplotlib to show it. The usual way to do things is to import matplotlib.pyplot and call show from there:
```
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000))
ts.plot()
plt.show()
```
In older versions of pandas, you were able to find a backdoor to matplotlib, as in the example below. NOTE: This no longer works in modern versions of pandas, and I still recommend importing matplotlib separately, as in the example above.
```
import numpy as np
import pandas as pd
ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000))
ts.plot()
pd.tseries.plotting.pylab.show()
```
But all you are doing there is finding somewhere that matplotlib has been imported in pandas, and calling the same show function from there. Are you trying to avoid calling matplotlib in an effort to speed things up? If so then you are really not speeding anything up, since pandas already imports pyplot:
```
python -mtimeit -s 'import pandas as pd'
100000000 loops, best of 3: 0.0122 usec per loop

python -mtimeit -s 'import pandas as pd; import matplotlib.pyplot as plt'
100000000 loops, best of 3: 0.0125 usec per loop
```
Finally, the reason the example you linked in comments doesn't need the call to matplotlib is because it is being run interactively in an iPython notebook, not in a script.


Question:
Matplotlib figure facecolor (background color) Can someone please explain why the code below does not work when setting the facecolor of the figure?
```
import matplotlib.pyplot as plt

# create figure instance
fig1 = plt.figure(1)
fig1.set_figheight(11)
fig1.set_figwidth(8.5)

rect = fig1.patch
rect.set_facecolor('red') # works with plt.show().
                          # Does not work with plt.savefig("trial_fig.png")

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

x = 1, 2, 3
y = 1, 4, 9
ax.plot(x, y)

# plt.show()  # Will show red face color set above using rect.set_facecolor('red')

plt.savefig("trial_fig.png") # The saved trial_fig.png DOES NOT have the red facecolor.

# plt.savefig("trial_fig.png", facecolor='red') # Here the facecolor is red.
```
When I specify the height and width of the figure using fig1.set_figheight(11) fig1.set_figwidth(8.5) these are picked up by the command plt.savefig("trial_fig.png"). However, the facecolor setting is not picked up. Why? Thanks for your help.

Response: It's because savefig overrides the facecolor for the background of the figure. (This is deliberate, actually... The assumption is that you'd probably want to control the background color of the saved figure with the facecolor kwarg to savefig. It's a confusing and inconsistent default, though!) The easiest workaround is just to do fig.savefig('whatever.png', facecolor=fig.get_facecolor(), edgecolor='none') (I'm specifying the edgecolor here because the default edgecolor for the actual figure is white, which will give you a white border around the saved figure)


Question: What is the difference between 'log' and 'symlog'? In matplotlib, I can set the axis scaling using either pyplot.xscale() or Axes.set_xscale(). Both functions accept three different scales: 'linear' | 'log' | 'symlog'. What is the difference between 'log' and 'symlog'? In a simple test I did, they both looked exactly the same. I know the documentation says they accept different parameters, but I still don't understand the difference between them. Can someone please explain it? The answer will be the best if it has some sample code and graphics! (also: where does the name 'symlog' come from?)

Response:
I finally found some time to do some experiments in order to understand the difference between them. Here's what I discovered: log only allows positive values, and lets you choose how to handle negative ones (mask or clip). symlog means symmetrical log, and allows positive and negative values. symlog allows to set a range around zero within the plot will be linear instead of logarithmic. I think everything will get a lot easier to understand with graphics and examples, so let's try them:
```
import numpy
from matplotlib import pyplot

# Enable interactive mode
pyplot.ion()

# Draw the grid lines
pyplot.grid(True)

# Numbers from -50 to 50, with 0.1 as step
xdomain = numpy.arange(-50,50, 0.1)

# Plots a simple linear function 'f(x) = x'
pyplot.plot(xdomain, xdomain)
# Plots 'sin(x)'
pyplot.plot(xdomain, numpy.sin(xdomain))

# 'linear' is the default mode, so this next line is redundant:
pyplot.xscale('linear')
```
```
# How to treat negative values?
# 'mask' will treat negative values as invalid
# 'mask' is the default, so the next two lines are equivalent
pyplot.xscale('log')
pyplot.xscale('log', nonposx='mask')
```
```
# 'clip' will map all negative values a very small positive one
pyplot.xscale('log', nonposx='clip')
```
```
# 'symlog' scaling, however, handles negative values nicely
pyplot.xscale('symlog')
```
```
# And you can even set a linear range around zero
pyplot.xscale('symlog', linthreshx=20)
```
Just for completeness, I've used the following code to save each figure:
```
# Default dpi is 80
pyplot.savefig('matplotlib_xscale_linear.png', dpi=50, bbox_inches='tight')
```
Remember you can change the figure size using:
```
fig = pyplot.gcf()
fig.set_size_inches([4., 3.])
# Default size: [8., 6.]
```
(If you are unsure about me answering my own question, read this)


Question:
matplotlib colorbar for scatter I'm working with data that has the data has 3 plotting parameters: x,y,c. How do you create a custom color value for a scatter plot? Extending this example I'm trying to do:
```
import matplotlib
import matplotlib.pyplot as plt
cm = matplotlib.cm.get_cmap('RdYlBu')
colors=[cm(1.*i/20) for i in range(20)]
xy = range(20)
plt.subplot(111)
colorlist=[colors[x/2] for x in xy] #actually some other non-linear relationship
plt.scatter(xy, xy, c=colorlist, s=35, vmin=0, vmax=20)
plt.colorbar()
plt.show()
```
but the result is TypeError: You must first set_array for mappable

Response:
From the matplotlib docs on scatter 1: cmap is only used if c is an array of floats So colorlist needs to be a list of floats rather than a list of tuples as you have it now. plt.colorbar() wants a mappable object, like the CircleCollection that plt.scatter() returns. vmin and vmax can then control the limits of your colorbar. Things outside vmin/vmax get the colors of the endpoints. How does this work for you?
```
import matplotlib.pyplot as plt
cm = plt.cm.get_cmap('RdYlBu')
xy = range(20)
z = xy
sc = plt.scatter(xy, xy, c=z, vmin=0, vmax=20, s=35, cmap=cm)
plt.colorbar(sc)
plt.show()
```


Question:
Plot a bar using matplotlib using a dictionary Is there any way to plot a bar plot using matplotlib using data directly from a dict? My dict looks like this:
```
D = {u'Label1':26, u'Label2': 17, u'Label3':30}
```
I was expecting
```
fig = plt.figure(figsize=(5.5,3),dpi=300)
ax = fig.add_subplot(111)
bar = ax.bar(D,range(1,len(D)+1,1),0.5)
```
to work, but it does not. Here is the error:
```

```python
ax.bar(D,range(1,len(D)+1,1),0.5)
#Output
#Traceback (most recent call last):
#  File "<stdin>", line 1, in <module>
#  File "/usr/local/lib/python2.7/site-packages/matplotlib/axes.py", line 4904, in bar
#    self.add_patch(r)
#  File "/usr/local/lib/python2.7/site-packages/matplotlib/axes.py", line 1570, in add_patch
#    self._update_patch_limits(p)
#  File "/usr/local/lib/python2.7/site-packages/matplotlib/axes.py", line 1588, in _update_patch_limits
#    xys = patch.get_patch_transform().transform(vertices)
#  File "/usr/local/lib/python2.7/site-packages/matplotlib/patches.py", line 580, in get_patch_transform
#    self._update_patch_transform()
#  File "/usr/local/lib/python2.7/site-packages/matplotlib/patches.py", line 576, in _update_patch_transform
#    bbox = transforms.Bbox.from_bounds(x, y, width, height)
#  File "/usr/local/lib/python2.7/site-packages/matplotlib/transforms.py", line 786, in from_bounds
#    return Bbox.from_extents(x0, y0, x0 + width, y0 + height)
#TypeError: coercing to Unicode: need string or buffer, float found
#```
```

Response:
You can do it in two lines by first plotting the bar chart and then setting the appropriate ticks:
```
import matplotlib.pyplot as plt

D = {u'Label1':26, u'Label2': 17, u'Label3':30}

plt.bar(range(len(D)), list(D.values()), align='center')
plt.xticks(range(len(D)), list(D.keys()))
# # for python 2.x:
# plt.bar(range(len(D)), D.values(), align='center')  # python 2.x
# plt.xticks(range(len(D)), D.keys())  # in python 2.x

plt.show()
```
Note that the penultimate line should read plt.xticks(range(len(D)), list(D.keys())) in python3, because D.keys() returns a generator, which matplotlib cannot use directly.


Question:
OpenCV giving wrong color to colored images on loading I'm loading in a color image in Python OpenCV and plotting the same. However, the image I get has it's colors all mixed up. Here is the code:
```
import cv2
import numpy as np
from numpy import array, arange, uint8
from matplotlib import pyplot as plt

img = cv2.imread('lena_caption.png', cv2.IMREAD_COLOR)
bw_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

images = []
images.append(img)
images.append(bw_img)

titles = ['Original Image','BW Image']

for i in xrange(len(images)):
    plt.subplot(1,2,i+1),plt.imshow(images[i],'gray')
    plt.title(titles[i])
    plt.xticks([]),plt.yticks([])

plt.show()
```
Here is the original image: And here is the plotted image:

Response:
OpenCV uses BGR as its default colour order for images, matplotlib uses RGB. When you display an image loaded with OpenCv in matplotlib the channels will be back to front. The easiest way of fixing this is to use OpenCV to explicitly convert it back to RGB, much like you do when creating the greyscale image.
```
RGB_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
```
And then use that in your plot.


Question:
plot with custom text for x axis points I am drawing a plot using matplotlib and python like the sample code below.
```
x = array([0,1,2,3])
y = array([20,21,22,23])
plot(x,y)
show()
```
As it is the code above on the x axis I will see drawn values 0.0, 0.5, 1.0, 1.5 i.e. the same values of my reference x values. Is there anyway to map each point of x to a different string? So for example I want x axis to show months names( strings Jun, July,...) or other strings like people names ( "John", "Arnold", ... ) or clock time ( "12:20", "12:21", "12:22", .. ). Do you know what I can do or what function to have a look at? For my purpose could it be matplotlib.ticker of help?

Response:
You can manually set xticks (and yticks) using pyplot.xticks:
```
import matplotlib.pyplot as plt
import numpy as np

x = np.array([0,1,2,3])
y = np.array([20,21,22,23])
my_xticks = ['John','Arnold','Mavis','Matt']
plt.xticks(x, my_xticks)
plt.plot(x, y)
plt.show()
```


Question:
Scatter plot and Color mapping in Python I have a range of points x and y stored in numpy arrays. Those represent x(t) and y(t) where t=0...T-1 I am plotting a scatter plot using
```
import matplotlib.pyplot as plt

plt.scatter(x,y)
plt.show()
```
I would like to have a colormap representing the time (therefore coloring the points depending on the index in the numpy arrays) What is the easiest way to do so?

Response:
Here is an example
```
import numpy as np
import matplotlib.pyplot as plt

x = np.random.rand(100)
y = np.random.rand(100)
t = np.arange(100)

plt.scatter(x, y, c=t)
plt.show()
```
Here you are setting the color based on the index, t, which is just an array of [1, 2, ..., 100]. Perhaps an easier-to-understand example is the slightly simpler
```
import numpy as np
import matplotlib.pyplot as plt

x = np.arange(100)
y = x
t = x
plt.scatter(x, y, c=t)
plt.show()
```
Note that the array you pass as c doesn't need to have any particular order or type, i.e. it doesn't need to be sorted or integers as in these examples. The plotting routine will scale the colormap such that the minimum/maximum values in c correspond to the bottom/top of the colormap. Colormaps You can change the colormap by adding
```
import matplotlib.cm as cm
plt.scatter(x, y, c=t, cmap=cm.cmap_name)
```
Importing matplotlib.cm is optional as you can call colormaps as cmap="cmap_name" just as well. There is a reference page of colormaps showing what each looks like. Also know that you can reverse a colormap by simply calling it as cmap_name_r. So either
```
plt.scatter(x, y, c=t, cmap=cm.cmap_name_r)
# or
plt.scatter(x, y, c=t, cmap="cmap_name_r")
```
will work. Examples are "jet_r" or cm.plasma_r. Here's an example with the new 1.5 colormap viridis:
```
import numpy as np
import matplotlib.pyplot as plt

x = np.arange(100)
y = x
t = x
fig, (ax1, ax2) = plt.subplots(1, 2)
ax1.scatter(x, y, c=t, cmap='viridis')
ax2.scatter(x, y, c=t, cmap='viridis_r')
plt.show()
```
Colorbars You can add a colorbar by using
```
plt.scatter(x, y, c=t, cmap='viridis')
plt.colorbar()
plt.show()
```
Note that if you are using figures and subplots explicitly (e.g. fig, ax = plt.subplots() or ax = fig.add_subplot(111)), adding a colorbar can be a bit more involved. Good examples can be found here for a single subplot colorbar and here for 2 subplots 1 colorbar.


Question:
Change figure window title in pylab How can I set a figure window's title in pylab/python?
```
fig = figure(9) # 9 is now the title of the window
fig.set_title("Test") #doesn't work
fig.title = "Test" #doesn't work
```

Response:
If you want to actually change the window you can do:
```
fig = pylab.gcf()
fig.canvas.manager.set_window_title('Test')
```


Question: Defining the midpoint of a colormap in matplotlib I want to set the middle point of a colormap, i.e., my data goes from -5 to 10 and I want zero to be the middle point. I think the way to do it is by subclassing normalize and using the norm, but I didn't find any example and it is not clear to me, what exactly have I to implement?

Response:
I know this is late to the game, but I just went through this process and came up with a solution that perhaps less robust than subclassing normalize, but much simpler. I thought it'd be good to share it here for posterity. The function
```
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import AxesGrid

def shiftedColorMap(cmap, start=0, midpoint=0.5, stop=1.0, name='shiftedcmap'):
    '''
    Function to offset the "center" of a colormap. Useful for
    data with a negative min and positive max and you want the
    middle of the colormap's dynamic range to be at zero.

    Input
    -----
      cmap : The matplotlib colormap to be altered
      start : Offset from lowest point in the colormap's range.
          Defaults to 0.0 (no lower offset). Should be between
          0.0 and `midpoint`.
      midpoint : The new center of the colormap. Defaults to
          0.5 (no shift). Should be between 0.0 and 1.0. In
          general, this should be  1 - vmax / (vmax + abs(vmin))
          For example if your data range from -15.0 to +5.0 and
          you want the center of the colormap at 0.0, `midpoint`
          should be set to  1 - 5/(5 + 15)) or 0.75
      stop : Offset from highest point in the colormap's range.
          Defaults to 1.0 (no upper offset). Should be between
          `midpoint` and 1.0.
    '''
    cdict = {
        'red': [],
        'green': [],
        'blue': [],
        'alpha': []
    }

    # regular index to compute the colors
    reg_index = np.linspace(start, stop, 257)

    # shifted index to match the data
    shift_index = np.hstack([
        np.linspace(0.0, midpoint, 128, endpoint=False),
        np.linspace(midpoint, 1.0, 129, endpoint=True)
    ])

    for ri, si in zip(reg_index, shift_index):
        r, g, b, a = cmap(ri)

        cdict['red'].append((si, r, r))
        cdict['green'].append((si, g, g))
        cdict['blue'].append((si, b, b))
        cdict['alpha'].append((si, a, a))

    newcmap = matplotlib.colors.LinearSegmentedColormap(name, cdict)
    plt.register_cmap(cmap=newcmap)

    return newcmap
```
An example
```
biased_data = np.random.random_integers(low=-15, high=5, size=(37,37))

orig_cmap = matplotlib.cm.coolwarm
shifted_cmap = shiftedColorMap(orig_cmap, midpoint=0.75, name='shifted')
shrunk_cmap = shiftedColorMap(orig_cmap, start=0.15, midpoint=0.75, stop=0.85, name='shrunk')

fig = plt.figure(figsize=(6,6))
grid = AxesGrid(fig, 111, nrows_ncols=(2, 2), axes_pad=0.5,
                label_mode="1", share_all=True,
                cbar_location="right", cbar_mode="each",
                cbar_size="7%", cbar_pad="2%")

# normal cmap
im0 = grid[0].imshow(biased_data, interpolation="none", cmap=orig_cmap)
grid.cbar_axes[0].colorbar(im0)
grid[0].set_title('Default behavior (hard to see bias)', fontsize=8)

im1 = grid[1].imshow(biased_data, interpolation="none", cmap=orig_cmap, vmax=15, vmin=-15)
grid.cbar_axes[1].colorbar(im1)
grid[1].set_title('Centered zero manually,\nbut lost upper end of dynamic range', fontsize=8)

im2 = grid[2].imshow(biased_data, interpolation="none", cmap=shifted_cmap)
grid.cbar_axes[2].colorbar(im2)
grid[2].set_title('Recentered cmap with function', fontsize=8)

im3 = grid[3].imshow(biased_data, interpolation="none", cmap=shrunk_cmap)
grid.cbar_axes[3].colorbar(im3)
grid[3].set_title('Recentered cmap with function\nand shrunk range', fontsize=8)

for ax in grid:
    ax.set_yticks([])
    ax.set_xticks([])
```
Results of the example:


Question:
Change grid interval and specify tick labels I am trying to plot counts in gridded plots, but I haven't been able to figure out how to go about it. I want: to have dotted grids at an interval of 5; to have major tick labels only every 20; for the ticks to be outside the plot; and to have "counts" inside those grids. I have checked for potential duplicates, such as here and here, but have not been able to figure it out. This is my code:
```py
import matplotlib.pyplot as plt
from matplotlib.ticker import MultipleLocator, FormatStrFormatter

for x, y, count in data.values():

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

    ax.annotate(count, xy = (x, y), size = 5)
    # overwrites and I only get the last data point

    plt.close()
    # Without this, I get a "fail to allocate bitmap" error.

plt.suptitle('Number of counts', fontsize = 12)
ax.set_xlabel('x')
ax.set_ylabel('y')
plt.axes().set_aspect('equal')

plt.axis([0, 1000, 0, 1000])
# This gives an interval of 200.

majorLocator   = MultipleLocator(20)
majorFormatter = FormatStrFormatter('%d')
minorLocator   = MultipleLocator(5)
# I want the minor grid to be 5 and the major grid to be 20.
plt.grid()
```
This is what I get.

Response:
There are several problems in your code. First the big ones: You are creating a new figure and a new axes in every iteration of your loop → put fig = plt.figure and ax = fig.add_subplot(1,1,1) outside of the loop. Don't use the Locators. Call the functions ax.set_xticks() and ax.grid() with the correct keywords. With plt.axes() you are creating a new axes again. Use ax.set_aspect('equal'). The minor things: You should not mix the MATLAB-like syntax like plt.axis() with the objective syntax. Use ax.set_xlim(a,b) and ax.set_ylim(a,b) This should be a working minimal example:
```
import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)

# Major ticks every 20, minor ticks every 5
major_ticks = np.arange(0, 101, 20)
minor_ticks = np.arange(0, 101, 5)

ax.set_xticks(major_ticks)
ax.set_xticks(minor_ticks, minor=True)
ax.set_yticks(major_ticks)
ax.set_yticks(minor_ticks, minor=True)

# And a corresponding grid
ax.grid(which='both')

# Or if you want different settings for the grids:
ax.grid(which='minor', alpha=0.2)
ax.grid(which='major', alpha=0.5)

plt.show()
```
Output is this:


Question:
How to set xticks in subplots If I plot a single imshow plot I can use
```py
fig, ax = plt.subplots()
ax.imshow(data)
plt.xticks( [4, 14, 24],  [5, 15, 25] )
```
to replace my xtick labels. Now, I am plotting 12 imshow plots using
```py
f, axarr = plt.subplots(4, 3)
axarr[i, j].imshow(data)
```
How can I change xticks just for one of these subplots? I can only access the axes of the subplots with axarr[i, j]. How can I access plt just for one particular subplot?

Response:
There are two ways: Use the axes methods of the subplot object (e.g. ax.set_xticks and ax.set_xticklabels) or Use plt.sca to set the current axes for the pyplot state machine (i.e. the plt interface). As an example (this also illustrates using setp to change the properties of all of the subplots):
```
import matplotlib.pyplot as plt

fig, axes = plt.subplots(nrows=3, ncols=4)

# Set the ticks and ticklabels for all axes
plt.setp(axes, xticks=[0.1, 0.5, 0.9], xticklabels=['a', 'b', 'c'],
        yticks=[1, 2, 3])

# Use the pyplot interface to change just one subplot...
plt.sca(axes[1, 1])
plt.xticks(range(3), ['A', 'Big', 'Cat'], color='red')

fig.tight_layout()
plt.show()
```


Question:
Getting vertical gridlines to appear in line plot in matplotlib I want to get both horizontal and vertical grid lines on my plot but only the horizontal grid lines are appearing by default. I am using a pandas.DataFrame from an sql query in python to generate a line plot with dates on the x-axis. I'm not sure why they do not appear on the dates and I have tried to search for an answer to this but couldn't find one. All I have used to plot the graph is the simple code below.
```
data.plot()
grid('on')
```
data is the DataFrame which contains the dates and the data from the sql query. I have also tried adding the code below but I still get the same output with no vertical grid lines.
```
ax = plt.axes()
ax.yaxis.grid() # horizontal lines
ax.xaxis.grid() # vertical lines
```
Any suggestions?

Response:
You may need to give boolean arg in your calls, e.g. use ax.yaxis.grid(True) instead of ax.yaxis.grid(). Additionally, since you are using both of them you can combine into ax.grid, which works on both, rather than doing it once for each dimension.
```
ax = plt.gca()
ax.grid(True)
```
That should sort you out.


Question:
prevent plot from showing in jupyter notebook How can I prevent a specific plot to be shown in Jupyter notebook? I have several plots in a notebook but I want a subset of them to be saved to a file and not shown on the notebook as this slows considerably. A minimal working example for a Jupyter notebook is:
```
%matplotlib inline
from numpy.random import randn
from matplotlib.pyplot import plot, figure
a=randn(3)
b=randn(3)
for i in range(10):
    fig=figure()
    plot(b)
    fname='s%03d.png'%i
    fig.savefig(fname)
    if(i%5==0):
        figure()
        plot(a)
```
As you can see I have two types of plots, a and b. I want a's to be plotted and shown and I don't want the b plots to be shown, I just want them them to be saved in a file. Hopefully this will speed things a bit and won't pollute my notebook with figures I don't need to see. Thank you for your time

Response:
Perhaps just clear the axis, for example:
```
fig = plt.figure()
plt.plot(range(10))
fig.savefig("save_file_name.pdf")
plt.close()
```
This will not plot the output in inline mode. I can't work out if it is really clearing the data though.


Question:
How to generate random colors in matplotlib? What's the trivial example of how to generate random colors for passing to plotting functions? I'm calling scatter inside a loop and want each plot a different color.
```
for X,Y in data:
   scatter(X, Y, c=??)
```
c: a color. c can be a single color format string, or a sequence of color specifications of length N, or a sequence of N numbers to be mapped to colors using the cmap and norm specified via kwargs (see below). Note that c should not be a single numeric RGB or RGBA sequence because that is indistinguishable from an array of values to be colormapped. c can be a 2-D array in which the rows are RGB or RGBA, however.

Response:
I'm calling scatter inside a loop and want each plot in a different color. Based on that, and on your answer: It seems to me that you actually want n distinct colors for your datasets; you want to map the integer indices 0, 1, ..., n-1 to distinct RGB colors. Something like: Here is the function to do it:
```
import matplotlib.pyplot as plt

def get_cmap(n, name='hsv'):
    '''Returns a function that maps each index in 0, 1, ..., n-1 to a distinct
    RGB color; the keyword argument name must be a standard mpl colormap name.'''
    return plt.cm.get_cmap(name, n)
```
Usage in your pseudo-code snippet in the question:
```
cmap = get_cmap(len(data))
for i, (X, Y) in enumerate(data):
   scatter(X, Y, c=cmap(i))
```
I generated the figure in my answer with the following code:
```
import matplotlib.pyplot as plt

def get_cmap(n, name='hsv'):
    '''Returns a function that maps each index in 0, 1, ..., n-1 to a distinct
    RGB color; the keyword argument name must be a standard mpl colormap name.'''
    return plt.cm.get_cmap(name, n)

def main():
    N = 30
    fig=plt.figure()
    ax=fig.add_subplot(111)
    plt.axis('scaled')
    ax.set_xlim([ 0, N])
    ax.set_ylim([-0.5, 0.5])
    cmap = get_cmap(N)
    for i in range(N):
        rect = plt.Rectangle((i, -0.5), 1, 1, facecolor=cmap(i))
        ax.add_artist(rect)
    ax.set_yticks([])
    plt.show()

if __name__=='__main__':
    main()
```
Tested with both Python 2.7 & matplotlib 1.5, and with Python 3.5 & matplotlib 2.0. It works as expected.


Question:
Plotting images side by side using matplotlib I was wondering how I am able to plot images side by side using matplotlib for example something like this: The closest I got is this: This was produced by using this code:
```
f, axarr = plt.subplots(2,2)
axarr[0,0] = plt.imshow(image_datas[0])
axarr[0,1] = plt.imshow(image_datas[1])
axarr[1,0] = plt.imshow(image_datas[2])
axarr[1,1] = plt.imshow(image_datas[3])
```
But I can't seem to get the other images to show. I'm thinking that there must be a better way to do this as I would imagine trying to manage the indexes would be a pain. I have looked through the documentation although I have a feeling I may be look at the wrong one. Would anyone be able to provide me with an example or point me in the right direction? EDIT: See the answer from @duhaime if you want a function to automatically determine the grid size.

Response:
The problem you face is that you try to assign the return of imshow (which is an matplotlib.image.AxesImage to an existing axes object. The correct way of plotting image data to the different axes in axarr would be
```
f, axarr = plt.subplots(2,2)
axarr[0,0].imshow(image_datas[0])
axarr[0,1].imshow(image_datas[1])
axarr[1,0].imshow(image_datas[2])
axarr[1,1].imshow(image_datas[3])
```
The concept is the same for all subplots, and in most cases the axes instance provide the same methods than the pyplot (plt) interface. E.g. if ax is one of your subplot axes, for plotting a normal line plot you'd use ax.plot(..) instead of plt.plot(). This can actually be found exactly in the source from the page you link to.


Question: Changing the color of an axis Is there a way to change the color of an axis (not the ticks) in matplotlib? I have been looking through the docs for Axes, Axis, and Artist, but no luck; the matplotlib gallery also has no hint. Any idea?

Response:
When using figures, you can easily change the spine color with:
```
ax.spines['bottom'].set_color('#dddddd')
ax.spines['top'].set_color('#dddddd')
ax.spines['right'].set_color('red')
ax.spines['left'].set_color('red')
```
Use the following to change only the ticks: which="both" changes both the major and minor tick colors
```py
ax.tick_params(axis='x', colors='red')
ax.tick_params(axis='y', colors='red')
```
And the following to change only the label:
```
ax.yaxis.label.set_color('red')
ax.xaxis.label.set_color('red')
```
And finally the title:
```
ax.title.set_color('red')
```


Question:
Histogram Matplotlib So I have a little problem. I have a data set in scipy that is already in the histogram format, so I have the center of the bins and the number of events per bin. How can I now plot is as a histogram. I tried just doing
```
bins, n=hist()
```
but it didn't like that. Any recommendations?

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

mu, sigma = 100, 15
x = mu + sigma * np.random.randn(10000)
hist, bins = np.histogram(x, bins=50)
width = 0.7 * (bins[1] - bins[0])
center = (bins[:-1] + bins[1:]) / 2
plt.bar(center, hist, align='center', width=width)
plt.show()
```
The object-oriented interface is also straightforward:
```
fig, ax = plt.subplots()
ax.bar(center, hist, align='center', width=width)
fig.savefig("1.png")
```
If you are using custom (non-constant) bins, you can pass compute the widths using np.diff, pass the widths to ax.bar and use ax.set_xticks to label the bin edges:
```
import matplotlib.pyplot as plt
import numpy as np

mu, sigma = 100, 15
x = mu + sigma * np.random.randn(10000)
bins = [0, 40, 60, 75, 90, 110, 125, 140, 160, 200]
hist, bins = np.histogram(x, bins=bins)
width = np.diff(bins)
center = (bins[:-1] + bins[1:]) / 2

fig, ax = plt.subplots(figsize=(8,3))
ax.bar(center, hist, align='center', width=width)
ax.set_xticks(bins)
fig.savefig("/tmp/out.png")

plt.show()
```


Question:
Linear regression with matplotlib / numpy I'm trying to generate a linear regression on a scatter plot I have generated, however my data is in list format, and all of the examples I can find of using polyfit require using arange. arange doesn't accept lists though. I have searched high and low about how to convert a list to an array and nothing seems clear. Am I missing something? Following on, how best can I use my list of integers as inputs to the polyfit? Here is the polyfit example I am following:
```
import numpy as np
import matplotlib.pyplot as plt

x = np.arange(data)
y = np.arange(data)

m, b = np.polyfit(x, y, 1)

plt.plot(x, y, 'yo', x, m*x+b, '--k')
plt.show()
```

Response:
arange generates lists (well, numpy arrays); type help(np.arange) for the details. You don't need to call it on existing lists.
```py

```python
x = [1,2,3,4]
```

```python
y = [3,5,7,9]
```

```python

```

```python
m,b = np.polyfit(x, y, 1)
```

```python
m
#Output
#2.0000000000000009
```

```python
b
#Output
#0.99999999999999833
#```
#I should add that I tend to use poly1d here rather than write out "m*x+b" and the higher-order equivalents, so my version of your code would look something like this:
#```py
#import numpy as np
#import matplotlib.pyplot as plt
```

x = [1,2,3,4]
y = [3,5,7,10] # 10, not 9, so the fit isn't perfect

coef = np.polyfit(x,y,1)
poly1d_fn = np.poly1d(coef)
# poly1d_fn is now a function which takes in x and returns an estimate for y

plt.plot(x,y, 'yo', x, poly1d_fn(x), '--k') #'--k'=black dashed line, 'yo' = yellow circle marker

plt.xlim(0, 5)
plt.ylim(0, 12)
```


Question:
Stop matplotlib repeating labels in legend Here is a very simplified example:
```
xvalues = [2,3,4,6]

for x in xvalues:
    plt.axvline(x,color='b',label='xvalues')

plt.legend()
```
The legend will now show 'xvalues' as a blue line 4 times in the legend. Is there a more elegant way of fixing this than the following?
```
for i,x in enumerate(xvalues):
    if not i:
        plt.axvline(x,color='b',label='xvalues')
    else:
        plt.axvline(x,color='b')
```

Response:
plt.legend takes as parameters A list of axis handles which are Artist objects A list of labels which are strings These parameters are both optional defaulting to plt.gca().get_legend_handles_labels(). You can remove duplicate labels by putting them in a dictionary before calling legend. This is because dicts can't have duplicate keys. For example: For Python versions < 3.7
```
from collections import OrderedDict
import matplotlib.pyplot as plt

handles, labels = plt.gca().get_legend_handles_labels()
by_label = OrderedDict(zip(labels, handles))
plt.legend(by_label.values(), by_label.keys())
```
For Python versions > 3.7 As of Python 3.7, dictionaries retain input order by default. Thus, there is no need for OrderedDict form the collections module.
```
import matplotlib.pyplot as plt

handles, labels = plt.gca().get_legend_handles_labels()
by_label = dict(zip(labels, handles))
plt.legend(by_label.values(), by_label.keys())
```
Docs for plt.legend


Question:
Why doesn't plt.imshow() display the image? I have this code, copied from a tutorial:
```
import numpy as np
np.random.seed(123)
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Convolution2D, MaxPooling2D
from keras.utils import np_utils
from keras.datasets import mnist
(X_train,y_train),(X_test,y_test) = mnist.load_data()
print X_train.shape
from matplotlib import pyplot as plt
plt.imshow(X_train[0])
```
No image was displayed. Why not? There doesn't appear to be anything wrong with the backend of matplotlib on my computer. I tested that like so:
```
import matplotlib.pyplot as plt

data = [[0, 0.25], [0.5, 0.75]]

fig, ax = plt.subplots()
im = ax.imshow(data, cmap=plt.get_cmap('hot'), interpolation='nearest',
               vmin=0, vmax=1)
fig.colorbar(im)
plt.show()
```
and was able to produce an image: I also tried printing X_train[0] and it looks right.

Response:
The solution was as simple as adding plt.show() at the end of the code snippet:
```
import numpy as np
np.random.seed(123)
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Convolution2D, MaxPooling2D
from keras.utils import np_utils
from keras.datasets import mnist
(X_train,y_train),(X_test,y_test) = mnist.load_data()
print X_train.shape
from matplotlib import pyplot as plt
plt.imshow(X_train[0])
plt.show()
```


Question:
How to add a second x-axis I have a very simple question. I need to have a second x-axis on my plot and I want that this axis has a certain number of tics that correspond to certain position of the first axis. Let's try with an example. Here I am plotting the dark matter mass as a function of the expansion factor, defined as 1/(1+z), that ranges from 0 to 1.
```
semilogy(1/(1+z),mass_acc_massive,'-',label='DM')
xlim(0,1)
ylim(1e8,5e12)
```
I would like to have another x-axis, on the top of my plot, showing the corresponding z for some values of the expansion factor. Is that possible? If yes, how can I have xtics ax

Response:
I'm taking a cue from the comments in @Dhara's answer, it sounds like you want to set a list of new_tick_locations by a function from the old x-axis to the new x-axis. The tick_function below takes in a numpy array of points, maps them to a new value and formats them:
```
import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()
ax1 = fig.add_subplot(111)
ax2 = ax1.twiny()

X = np.linspace(0,1,1000)
Y = np.cos(X*20)

ax1.plot(X,Y)
ax1.set_xlabel(r"Original x-axis: $X$")

new_tick_locations = np.array([.2, .5, .9])

def tick_function(X):
    V = 1/(1+X)
    return ["%.3f" % z for z in V]

ax2.set_xlim(ax1.get_xlim())
ax2.set_xticks(new_tick_locations)
ax2.set_xticklabels(tick_function(new_tick_locations))
ax2.set_xlabel(r"Modified x-axis: $1/(1+X)$")
plt.show()
```


Question:
How to set the range of y-axis for a seaborn boxplot [duplicate] This question already has answers here: How to set the axis limits in Matplotlib? (10 answers) Closed 2 years ago. From the official seaborn documentation, I learned that you can create a boxplot as below:
```py
import seaborn as sns
sns.set_style("whitegrid")
tips = sns.load_dataset("tips")
ax = sns.boxplot(x="day", y="total_bill", data=tips)
```
My question is: how do I limit the range of y-axis of this plot? For example, I want the y-axis to be within [10, 40]. Is there any easy way to do this?

Response:
It is standard matplotlib.pyplot:
```
import matplotlib.pyplot as plt

plt.ylim(10, 40)
```
Or simpler, as mwaskom comments below:
```
ax.set(ylim=(10, 40))
```


Question:
How to forget previous plots - how can I flush/refresh? How do you get matplotlib.pyplot to "forget" previous plots I am trying to plot multiple time using matplotlib.pyplot The code looks like this:
```
def plottest():
    import numpy as np
    import matplotlib.pyplot as plt

    a=np.random.rand(10,)
    b=np.random.rand(10,)
    c=np.random.rand(10,)

    plt.plot(a,label='a')
    plt.plot(b,label='b')
    plt.plot(c,label='c')
    plt.legend(loc='upper left')
    plt.ylabel('mag')
    plt.xlabel('element)')
    plt.show()

    e=np.random.rand(10,)
    f=np.random.rand(10,)
    g=np.random.rand(10,)

    plt.plot(e,label='e')
    plt.plot(f,label='f')
    plt.plot(g,label='g')
    plt.legend(loc='upper left')
    plt.ylabel('mag')
    plt.xlabel('element)')
    plt.show()
```
Unfortunately I keep getting the same plot (actually from some other code which I ran and completed a while ago) no matter what I do. Similar code has worked previously for me. I have looked at these questions: How to "clean the slate"? Matplotlib pyplot show() doesn't work once closed (python) matplotlib pyplot show() .. blocking or not? and tried using plt.show(), plt.clf() and plt.close to no avail. Any ideas?

Response:
I would rather use plt.clf() after every plt.show() to just clear the current figure instead of closing and reopening it, keeping the window size and giving you a better performance and much better memory usage. Similarly, you could do plt.cla() to just clear the current axes. To clear a specific axes, useful when you have multiple axes within one figure, you could do for example:
```
fig, axes = plt.subplots(nrows=2, ncols=2)

axes[0, 1].clear()
```