Question:
Move and resize legends-box in matplotlib I'm creating plots using Matplotlib that I save as SVG, export to .pdf + .pdf_tex using Inkscape, and include the .pdf_tex-file in a LaTeX document. This means that I can input LaTeX-commands in titles, legends etc., giving an image like this which renders like this when I use it in my LaTeX document. Notice that the font for the numbers on the axes change, and the LaTeX-code in the legend is compiled: Code for the plot (how to export to SVG not shown here, but can be shown on request):
```
import numpy as np
x = np.linspace(0,1,100)
y = x**2

import matplotlib.pyplot as plt
plt.plot(x, y, label = '{\\footnotesize \$y = x^2\$}')
plt.legend(loc = 'best')
plt.show()
```
The problem is, as you can see, that the alignment and size of the box around the legend is wrong. This is because the size of the text of the label changes when the image is passed through Inkscape + pdflatex (because \footnotesize etc. disappears, and the font size changes). I have figured out that I can choose the placement of the label by either
```
plt.label(loc = 'upper right')
```
or if I want more control I can use
```
plt.label(bbox_to_anchor = [0.5, 0.2])
```
but I haven't found any way of making the box around the label smaller. Is this possible? An alternative to making the box smaller is to remove the outline of the box using something like
```
legend = plt.legend()
legend.get_frame().set_edgecolor('1.0')
```
and then moving the label to where I want it. In that case I would like to be able to set the placement of the label by first letting python/matplotlib place it using
```
plt.label(loc = 'upper right')
```
and then for example moving it a bit to the right. Is this possible? I have tried using get_bbox_to_anchor() and set_bbox_to_anchor(), but can't seem to get it to work.

Response:
You can move a legend after automatically placing it by drawing it, and then getting the bbox position. Here's an example:
```
import matplotlib.pyplot as plt
import numpy as np

# Plot data
x = np.linspace(0,1,100)
y = x**2
fig = plt.figure()
ax = fig.add_subplot(221) #small subplot to show how the legend has moved.

# Create legend
plt.plot(x, y, label = '{\\footnotesize \$y = x^2\$}')
leg = plt.legend( loc = 'upper right')

plt.draw() # Draw the figure so you can find the positon of the legend.

# Get the bounding box of the original legend
bb = leg.get_bbox_to_anchor().transformed(ax.transAxes.inverted())

# Change to location of the legend.
xOffset = 1.5
bb.x0 += xOffset
bb.x1 += xOffset
leg.set_bbox_to_anchor(bb, transform = ax.transAxes)

# Update the plot
plt.show()
```


Question:
Changing marker style in scatter plot according to third variable I am dealing with a multi-column dictionary. I want to plot two columns and subsequently change color and style of the markers according to a third and fourth column. I struggle with changing the marker style in the pylab scatter plot. My approach, which works for color, unfortunately does not work for marker style.
```
x=[1,2,3,4,5,6]
y=[1,3,4,5,6,7]
m=['k','l','l','k','j','l']

for i in xrange(len(m)):
    m[i]=m[i].replace('j','o')
    m[i]=m[i].replace('k','x')
    m[i]=m[i].replace('l','+')

plt.scatter(x,y,marker=m)
plt.show()
```

Response:
The problem is that marker can only be a single value and not a list of markers, as the color parmeter. You can either do a grouping by marker value so you have the x and y lists that have the same marker and plot them:
```
xs = [[1, 2, 3], [4, 5, 6]]
ys = [[1, 2, 3], [4, 5, 6]]
m = ['o', 'x']
for i in range(len(xs)):
    plt.scatter(xs[i], ys[i], marker=m[i])
plt.show()
```
Or you can plot every single dot (which I would not recommend):
```
x=[1,2,3,4,5,6]
y=[1,3,4,5,6,7]
m=['k','l','l','k','j','l']

mapping = {'j' : 'o', 'k': 'x', 'l': '+'}

for i in range(len(x)):
    plt.scatter(x[i], y[i], marker=mapping[m[i]])
plt.show()
```


Question:
Dynamically serving a matplotlib image to the web using python This question has been asked in a similar way here but the answer was way over my head (I'm super new to python and web development) so I'm hoping there's a simpler way or it could be explained differently. I'm trying to generate an image using matplotlib and serve it without first writing a file to the server. My code is probably kind of silly, but it goes like this:
```
import cgi
import matplotlib.pyplot as pyplot
import cStringIO #I think I will need this but not sure how to use

...a bunch of matplotlib stuff happens....
pyplot.savefig('test.png')

print "Content-type: text/html\n"
print """<html><body>
...a bunch of text and html here...
<img src="test.png"></img>
...more text and html...
</body></html>
"""
```
I think that instead of doing pyplot.savefig('test.png'), I am supposed to create a cstringIO object and then do something like this:
```
mybuffer=cStringIO.StringIO()
pyplot.savefig(mybuffer, format="png")
```
But I am pretty lost from there. All the examples I've seen (e.g. http://lost-theory.org/python/dynamicimg.html) involve doing something like
```
print "Content-type: image/png\n"
```
and I don't get how to integrate that with the HTML I'm already outputting.

Response:
You should first write to a cStringIO object then write the HTTP header then write the content of the cStringIO to stdout Thus, if an error in savefig occured, you could still return something else, even another header. Some errors won't be recognized earlier, e.g., some problems with texts, too large image dimensions etc. You need to tell savefig where to write the output. You can do:
```
format = "png"
sio = cStringIO.StringIO()
pyplot.savefig(sio, format=format)
print "Content-Type: image/%s\n" % format
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) # Needed this on windows, IIS
sys.stdout.write(sio.getvalue())
```
If you want to embed the image into HTML:
```
print "Content-Type: text/html\n"
print """<html><body>
...a bunch of text and html here...
<img src="data:image/png;base64,%s"/>
...more text and html...
</body></html>""" % sio.getvalue().encode("base64").strip()
```


Question:
matplotlib: log transform counts in hist2d Is there a simple way to get log transformed counts when plotting a two dimensional histogram in matplotlib? Unlike the pyplot.hist method, the pyplot.hist2d method does not seem to have a log parameter. Currently I'm doing the following:
```
import numpy as np
import matplotlib as mpl
import matplotlib.pylab as plt

matrix, *opt = np.histogram2d(x, y)
img = plt.imshow(matrix, norm = mpl.colors.LogNorm(), cmap = mpl.cm.gray,
                 interpolation="None")
```
Which plots the expected histogram, but the axis labels show the indices of the bins and thus not the expected value.

Response:
It's kind of embarrassing, but the answer to my question is actually in the docstring of the corresponding code:
```
Notes
-----
    Rendering the histogram with a logarithmic color scale is
    accomplished by passing a :class:`colors.LogNorm` instance to
    the *norm* keyword argument. Likewise, power-law normalization
    (similar in effect to gamma correction) can be accomplished with
    :class:`colors.PowerNorm`.
```
So this works:
```
import matplotlib as mpl
import matplotlib.pylab as plt
par = plt.hist2d(x, y, norm=mpl.colors.LogNorm(), cmap=mpl.cm.gray)
```


Question:
Correcting matplotlib colorbar ticks I've placed a color bar alongside a choropleth map. Because the data being plotted are discrete rather than continuous values, I've used a LinearSegmentedColormap (using the recipe from the scipy cookbook), which I've initialised with my max counted value + 1, in order to show a colour for 0. However, I now have two problems: The tick labels are incorrectly spaced (except for 5, more or less) – they should be located in the middle of the colour they identify; i.e. 0 - 4 should be moved up, and 6 - 10 should be moved down. If I initialise the colorbar with drawedges=True, so that I can style its dividers properties, I get this: I'm creating my colormap and colorbar like so:
```
cbmin, cbmax = min(counts), max(counts)
# this normalises the counts to a 0,1 interval
counts /= np.max(np.abs(counts), axis=0)
# density is a discrete number, so we have to use a discrete color ramp/bar
cm = cmap_discretize(plt.get_cmap('YlGnBu'), int(cbmax) + 1)
mappable = plt.cm.ScalarMappable(cmap=cm)
mappable.set_array(counts)
# set min and max values for the colour bar ticks
mappable.set_clim(cbmin, cbmax)
pc = PatchCollection(patches, match_original=True)
# impose our colour map onto the patch collection
pc.set_facecolor(cm(counts))
ax.add_collection(pc,)
cb = plt.colorbar(mappable, drawedges=True)
```
So I'm wondering whether my converting the counts to a 0,1 interval is one of the problems. Update : Having tried what Hooked suggested, the 0-value is correct, but subsequent values are set progressively higher, to the the point where 9 is where 10 should be: Here's the code I used:
```
cb = plt.colorbar(mappable)
labels = np.arange(0, int(cbmax) + 1, 1)
loc = labels + .5
cb.set_ticks(loc)
cb.set_ticklabels(labels)
```
And just to confirm, labels definitely has the correct values:
```

```python
np.arange(0, int(cbmax) + 1, 1)
#Output
#array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10])
#```
```

Response:
You are suffering from an off-by-one error. You have 10 ticklabels spread among 11 colors. You might be able to correct the error by using np.linspace instead of np.arange. Using np.linspace the third argument is the number of values desired. This reduces the amount of mental gymnastics needed to avoid the off-by-one error:
```
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.cm as cm
import matplotlib.colors as mcolors

def colorbar_index(ncolors, cmap):
    cmap = cmap_discretize(cmap, ncolors)
    mappable = cm.ScalarMappable(cmap=cmap)
    mappable.set_array([])
    mappable.set_clim(-0.5, ncolors+0.5)
    colorbar = plt.colorbar(mappable)
    colorbar.set_ticks(np.linspace(0, ncolors, ncolors))
    colorbar.set_ticklabels(range(ncolors))

def cmap_discretize(cmap, N):
    """Return a discrete colormap from the continuous colormap cmap.

        cmap: colormap instance, eg. cm.jet.
        N: number of colors.

    Example
        x = resize(arange(100), (5,100))
        djet = cmap_discretize(cm.jet, 5)
        imshow(x, cmap=djet)
    """

    if type(cmap) == str:
        cmap = plt.get_cmap(cmap)
    colors_i = np.concatenate((np.linspace(0, 1., N), (0.,0.,0.,0.)))
    colors_rgba = cmap(colors_i)
    indices = np.linspace(0, 1., N+1)
    cdict = {}
    for ki,key in enumerate(('red','green','blue')):
        cdict[key] = [ (indices[i], colors_rgba[i-1,ki], colors_rgba[i,ki])
                       for i in xrange(N+1) ]
    # Return colormap object.
    return mcolors.LinearSegmentedColormap(cmap.name + "_%d"%N, cdict, 1024)

fig, ax = plt.subplots()
A = np.random.random((10,10))*10
cmap = plt.get_cmap('YlGnBu')
ax.imshow(A, interpolation='nearest', cmap=cmap)
colorbar_index(ncolors=11, cmap=cmap)
plt.show()
```


Question: Dates in the xaxis for a matplotlib plot with imshow So I am new to programming with matplotlib. I have created a color plot using imshow() and an array. At first the axis were just the row and column number of my array. I used extent = (xmin,xmax,ymin,ymax) to get the x-axis in unix time and altitude, respectively. I want to change the x-axis from unix time (982376726,982377321) to UT(02:25:26, 02:35:21). I have created a list of the time range in HH:MM:SS. I am not sure how to replace my current x-axis with these new numbers, without changing the color plot (or making it disappear). I was looking at datetime.time but I got confused with it. Any help would be greatly appreciated!

Response:
I have put together some example code which should help you with your problem. The code first generates some randomised data using numpy.random. It then calculates your x-limits and y-limits where the x-limits will be based off of two unix timestamps given in your question and the y-limits are just generic numbers. The code then plots the randomised data and uses pyplot methods to convert the x-axis formatting to nicely represented strings (rather than unix timestamps or array numbers). The code is well commented and should explain everything you need, if not please comment and ask for clarification.
```
import numpy as np
import matplotlib.pyplot as plt

import matplotlib.dates as mdates

import datetime as dt

# Generate some random data for imshow
N = 10
arr = np.random.random((N, N))

# Create your x-limits. Using two of your unix timestamps you first
# create a list of datetime.datetime objects using map.
x_lims = list(map(dt.datetime.fromtimestamp, [982376726, 982377321]))

# You can then convert these datetime.datetime objects to the correct
# format for matplotlib to work with.
x_lims = mdates.date2num(x_lims)

# Set some generic y-limits.
y_lims = [0, 100]

fig, ax = plt.subplots()

# Using ax.imshow we set two keyword arguments. The first is extent.
# We give extent the values from x_lims and y_lims above.
# We also set the aspect to "auto" which should set the plot up nicely.
ax.imshow(arr, extent = [x_lims[0], x_lims[1],  y_lims[0], y_lims[1]],
          aspect='auto')

# We tell Matplotlib that the x-axis is filled with datetime data,
# this converts it from a float (which is the output of date2num)
# into a nice datetime string.
ax.xaxis_date()

# We can use a DateFormatter to choose how this datetime string will look.
# I have chosen HH:MM:SS though you could add DD/MM/YY if you had data
# over different days.
date_format = mdates.DateFormatter('%H:%M:%S')

ax.xaxis.set_major_formatter(date_format)

# This simply sets the x-axis data to diagonal so it fits better.
fig.autofmt_xdate()

plt.show()
```


Question:
How to change marker size with pandas.plot() I have a chart created from df.plot(style="o") where the o markers are too big. Would it be possible to size them down?
```
import pandas as pd
df = pd.DataFrame(range(1, 10))
df.plot(style="o")
```
How can I shrink them down?

Response:
After investigation, it looks like that you can pass the ms, short for markersize (which also work) argument directly to pandas.plot() such has:
```
import pandas as pd
df = pd.DataFrame(range(1, 10))
df.plot(style="o", ms=3)
```


Question: matplotlib set shared axis [duplicate] This question already has answers here: How to share x axes of two subplots after they have been created (6 answers) Closed 3 years ago. Using matplotlib, it seems the only time to set the sharex or sharey axis parameters are during sub_plot creation (add_subplot(), subplot(), subplots()). For an axes class there are methods for getting axis sharing (get_shared_x_axes(), get_shared_y_axes()), but no corresponding methods for setting sharing. Maybe this is an API oversight, or perhaps it did not fit architecturally. Is there a way to change the shared axis parameter? For those that ask why: I'm using a matrix of plots dynamically, and can control this using view limits, but it just seems like there could be an easier way, and turning sharing on/off and using autoscale would be it. Thanks.

Response:
Just to mention that a method for sharing axes after their creation does exist by now. For two axes ax1 and ax2 you can use
```
ax1.get_shared_x_axes().join(ax1, ax2)
```
See How share x axis of two subplots after they are created?.


Question:
Linestyle in matplotlib step function Is it possible to set the linestyle in a matplotlib step function to dashed, dotted, etc.? I've tried:
```
step(x, linestyle='--'),
step(x, '--')
```
But it did not help.

Response:
As of mpl 1.3.0 this is fixed upstream You have to come at it a bit sideways as step seems to ignore linestyle. If you look at what step is doing underneath, it is just a thin wrapper for plot. You can do what you want by talking to plot directly:
```
import matplotlib.pyplot as plt

plt.plot(range(5), range(5), linestyle='--', drawstyle='steps')
plt.plot(range(5), range(5)[::-1], linestyle=':', drawstyle='steps')
plt.xlim([-1, 5])
plt.ylim([-1, 5])
```
['steps', 'steps-pre', 'steps-mid', 'steps-post'] are the valid values for drawstyle and control where the step is drawn. Pull request resulting from this question, I personally think this is a bug. [edit: this has been pulled into master and should show up in v1.3.0].


Question:
Position 5 subplots in Matplotlib I would like to position 5 subplots such that there are three of top and two at the bottom but next to each other. The current code gets close but I would like the final result to look like the following (ignore gray lines):
```
import matplotlib.pyplot as plt

ax1 = plt.subplot(231)
ax2 = plt.subplot(232)
ax3 = plt.subplot(233)
ax4 = plt.subplot(234)
ax5 = plt.subplot(236)

plt.show()
```

Response:
You can use colspan When you use suplot2grid instead of subplot.
```
import matplotlib.pyplot as plt

ax1 = plt.subplot2grid(shape=(2,6), loc=(0,0), colspan=2)
ax2 = plt.subplot2grid((2,6), (0,2), colspan=2)
ax3 = plt.subplot2grid((2,6), (0,4), colspan=2)
ax4 = plt.subplot2grid((2,6), (1,1), colspan=2)
ax5 = plt.subplot2grid((2,6), (1,3), colspan=2)
```
And then every subplot needs to be 2 cols wide, so that the subplots in the second row can be shifted by 1 column.


Question: matplotlib: add circle to plot How do I add a small filled circle or point to a countour plot in matplotlib?

Response:
Here is an example, using pylab.Circle:
```
import numpy as np
import matplotlib.pyplot as plt

e = np.e
X, Y = np.meshgrid(np.linspace(0, 5, 100), np.linspace(0, 5, 100))
F = X ** Y
G = Y ** X

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
circ = plt.Circle((e, e), radius=0.07, color='g')
plt.contour(X, Y, (F - G), [0])
ax.add_patch(circ)
plt.show()
```
And here is another example (though not a contour plot) from the docs. Or, you could just use plot:
```
import numpy as np
import matplotlib.pyplot as plt

e = np.e
X, Y = np.meshgrid(np.linspace(0, 5, 100), np.linspace(0, 5, 100))
F = X ** Y
G = Y ** X

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
plt.contour(X, Y, (F - G), [0])
plt.plot([e], [e], 'g.', markersize=20.0)
plt.show()
```


Question:
matplotlib large set of colors for plots I have a lot of graphs I want to plot in one plot. I've just started with matplotlib and can't find a good way to generate a lot of distinguishable colors :( Maybe cycling over HSV with SV at maximum? I'm thinking of something like
```
args=[]
for i,(x,y) in enumerate(data):
    args.extend([x,y,hsv(i)])
plot(*args)
```
Any suggestions? :)

Response:
I think you have the right idea, except that the colors will be more distinguishable if you pass the colormap hsv numbers which are spread out over the range (0,1):
```
hsv = plt.get_cmap('hsv')
hsv(float(i)/(len(data)-1))
```
or, using NumPy:
```
colors = hsv(np.linspace(0, 1.0, len(kinds)))
```
For example:
```
import datetime as DT
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import scipy.interpolate as interpolate

dates = [DT.date(year, 9, 1) for year in range(2003, 2009)]
t = list(map(mdates.date2num, dates))
jec = (100, 70, 125, 150, 300, 250)
plt.plot(dates, jec, 'k.', markersize = 20)
new_t = np.linspace(min(t), max(t), 80)
new_dates = map(mdates.num2date, new_t)
kinds = ('cubic', 'quadratic', 'slinear', 'nearest', 'linear', 'zero', 4, 5)
cmap = plt.get_cmap('jet')
colors = cmap(np.linspace(0, 1.0, len(kinds)))
for kind, color in zip(kinds, colors):
    new_jec = interpolate.interp1d(t, jec, kind=kind)(new_t)
    plt.plot(new_t, new_jec, '-', label=str(kind), color=color)
plt.legend(loc = 'best')
plt.show()
```


Question:
Set size of subplot in matplotlib [duplicate] This question already has answers here: How do I change the figure size with subplots? (6 answers) Closed 2 years ago. I wonder how to set the size of the subplot when figure contains multiple subplots (5 × 2 in my case). No matter how big I allow the whole figure to be, the subplots always seem to be small. I would like to have direct control of the size of the subplot in this figure. The simplified version of the code is pasted below.
```
import numpy as np
import matplotlib.pyplot as plt

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

fig = plt.figure(figsize=(20, 8))

for i in range(0,10):
    ax = fig.add_subplot(5, 2, i+1)
    plt.plot(x, y, 'o')
    ax.xaxis.set_visible(False)
    ax.yaxis.set_visible(False)
    # x and y axis should be equal length
    x0,x1 = ax.get_xlim()
    y0,y1 = ax.get_ylim()
    ax.set_aspect(abs(x1-x0)/abs(y1-y0))

plt.show()
fig.savefig('plot.pdf', bbox_inches='tight')
```

Response:
Just switch figure size width and height from:
```
fig = plt.figure(figsize=(20, 8))
```
to:
```
fig = plt.figure(figsize=(8, 20))
```
to use the whole page for your plots. This will change your plot from: to:


Question:
Python: Frequency of occurrences I have list of integers and want to get frequency of each integer. This was discussed here The problem is that approach I'm using gives me frequency of floating numbers when my data set consist of integers only. Why that happens and how I can get frequency of integers from my data? I'm using pyplot.histogram to plot a histogram with frequency of occurrences
```
import numpy as np
import matplotlib.pyplot as plt
from numpy import *
data = loadtxt('data.txt',dtype=int,usecols=(4,)) #loading 5th column of csv file into array named data.
plt.hist(data) #plotting the column as histogram
```
I'm getting the histogram, but I've noticed that if I "print" hist(data)
```
hist=np.histogram(data)
print hist(data)
```
I get this:
```
(array([ 2323, 16338,  1587,   212,    26,    14,     3,     2,     2,     2]),
array([  1. ,   2.8,   4.6,   6.4,   8.2,  10. ,  11.8,  13.6,  15.4,
    17.2,  19. ]))
```
Where the second array represent values and first array represent number of occurrences. In my data set all values are integers, how that happens that second array have floating numbers and how should I get frequency of integers? UPDATE: This solves the problem, thank you Lev for the reply.
```
plt.hist(data, bins=np.arange(data.min(), data.max()+1))
```
To avoid creating a new question how I can plot columns "in the middle" for each integer? Say, I want column for integer 3 take space between 2.5 and 3.5 not between 3 and 4.

Response:
If you don't specify what bins to use, np.histogram and pyplot.hist will use a default setting, which is to use 10 equal bins. The left border of the 1st bin is the smallest value and the right border of the last bin is the largest. This is why the bin borders are floating point numbers. You can use the bins keyword arguments to enforce another choice of bins, e.g.:
```
plt.hist(data, bins=np.arange(data.min(), data.max()+1))
```
Edit: the easiest way to shift all bins to the left is probably just to subtract 0.5 from all bin borders:
```
plt.hist(data, bins=np.arange(data.min(), data.max()+1)-0.5)
```
Another way to achieve the same effect (not equivalent if non-integers are present):
```
plt.hist(data, bins=np.arange(data.min(), data.max()+1), align='left')
```


Question: Cannot edit text in chart exported by Matplotlib and opened in Illustrator I am exporting charts from matplotlib and editing them in Illustrator. It's great that I can edit the lines, but the text also comes in as lines, so I cannot change fonts, edit text, etc. I've exported as EPS, PDF, and PS with the same issues. I'm using matplotlib version 1.0.1 with python 2.7.1 on OSX Snow Leaopard. I appreciate any insights offered! I tried using pdf2ps as suggested here, but all that did was degrade the quality of the image without making the text rendered as real text. pdftops looked nicer, but still can't edit the text results.

Response:
You can edit the text in Acrobat/Illustrator if you set pdf.fonttype to 42 (TrueType), and export in pdf. You can set this in your ~/matplotlib/matplotlibrc:
```
pdf.fonttype : 42 # Output Type 3 (Type3) or Type 42 (TrueType)
```
..or dynamically:
```

```python
import matplotlib as mpl
```

```python
mpl.rcParams['pdf.fonttype'] = 42
#Output
#```
#Apparently it defaults to Type3 which Acrobat/Illustrator can't deal with.
```


Question:
Find the area between two curves plotted in matplotlib (fill_between area) I have a list of x and y values for two curves, both having weird shapes, and I don't have a function for any of them. I need to do two things: Plot it and shade the area between the curves like the image below. Find the total area of this shaded region between the curves. I'm able to plot and shade the area between those curves with fill_between and fill_betweenx in matplotlib, but I have no idea on how to calculate the exact area between them, specially because I don't have a function for any of those curves. Any ideas? I looked everywhere and can't find a simple solution for this. I'm quite desperate, so any help is much appreciated. Thank you very much! EDIT: For future reference (in case anyone runs into the same problem), here is how I've solved this: connected the first and last node/point of each curve together, resulting in a big weird-shaped polygon, then used shapely to calculate the polygon's area automatically, which is the exact area between the curves, no matter which way they go or how nonlinear they are. Works like a charm! :) Here is my code:
```py
from shapely.geometry import Polygon

x_y_curve1 = [(0.121,0.232),(2.898,4.554),(7.865,9.987)] #these are your points for curve 1 (I just put some random numbers)
x_y_curve2 = [(1.221,1.232),(3.898,5.554),(8.865,7.987)] #these are your points for curve 2 (I just put some random numbers)

polygon_points = [] #creates a empty list where we will append the points to create the polygon

for xyvalue in x_y_curve1:
    polygon_points.append([xyvalue[0],xyvalue[1]]) #append all xy points for curve 1

for xyvalue in x_y_curve2[::-1]:
    polygon_points.append([xyvalue[0],xyvalue[1]]) #append all xy points for curve 2 in the reverse order (from last point to first point)

for xyvalue in x_y_curve1[0:1]:
    polygon_points.append([xyvalue[0],xyvalue[1]]) #append the first point in curve 1 again, to it "closes" the polygon

polygon = Polygon(polygon_points)
area = polygon.area
print(area)
```
EDIT 2: Thank you for the answers. Like Kyle explained, this only works for positive values. If your curves go below 0 (which is not my case, as showed in the example chart), then you would have to work with absolute numbers.

Response:
The area calculation is straightforward in blocks where the two curves don't intersect: thats the trapezium as has been pointed out above. If they intersect, then you create two triangles between x[i] and x[i+1], and you should add the area of the two. If you want to do it directly, you should handle the two cases separately. Here's a basic working example to solve your problem. First, I will start with some fake data:
```
#!/usr/bin/python
import numpy as np

# let us generate fake test data
x = np.arange(10)
y1 = np.random.rand(10) * 20
y2 = np.random.rand(10) * 20
```
Now, the main code. Based on your plot, looks like you have y1 and y2 defined at the same X points. Then we define,
```
z = y1-y2
dx = x[1:] - x[:-1]
cross_test = np.sign(z[:-1] * z[1:])
```
cross_test will be negative whenever the two graphs cross. At these points, we want to calculate the x coordinate of the crossover. For simplicity, I will calculate x coordinates of the intersection of all segments of y. For places where the two curves don't intersect, they will be useless values, and we won't use them anywhere. This just keeps the code easier to understand. Suppose you have z1 and z2 at x1 and x2, then we are solving for x0 such that z = 0:
```
# (z2 - z1)/(x2 - x1) = (z0 - z1) / (x0 - x1) = -z1/(x0 - x1)
# x0 = x1 - (x2 - x1) / (z2 - z1) * z1
x_intersect = x[:-1] - dx / (z[1:] - z[:-1]) * z[:-1]
dx_intersect = - dx / (z[1:] - z[:-1]) * z[:-1]
```
Where the curves don't intersect, area is simply given by:
```
areas_pos = abs(z[:-1] + z[1:]) * 0.5 * dx # signs of both z are same
```
Where they intersect, we add areas of both triangles:
```
areas_neg = 0.5 * dx_intersect * abs(z[:-1]) + 0.5 * (dx - dx_intersect) * abs(z[1:])
```
Now, the area in each block x[i] to x[i+1] is to be selected, for which I use np.where:
```
areas = np.where(cross_test < 0, areas_neg, areas_pos)
total_area = np.sum(areas)
```
That is your desired answer. As has been pointed out above, this will get more complicated if the both the y graphs were defined at different x points. If you want to test this, you can simply plot it (in my test case, y range will be -20 to 20)
```
negatives = np.where(cross_test < 0)
positives = np.where(cross_test >= 0)
plot(x, y1)
plot(x, y2)
plot(x, z)
plt.vlines(x_intersect[negatives], -20, 20)
```


Question:
scatter plot in matplotlib This is my first matplotlib program, so sorry for my ignorance. I've two arrays of string. say, A = ['test1','test2'] and B = ['test3','test4']. If any correlation exists between A and B element, their corr value will be set to 1.
```
test1 | test2
test3 |   1   |   0

test4 |   0   |   1
```
Now, I want to draw a scatter diagram where my X axis will be elements of A, Y axis will be elements of B and if correlation value is 1, it'll be marked in the scattered plot. how to do that?

Response:
Maybe something like this:
```
import matplotlib.pyplot
import pylab

x = [1,2,3,4]
y = [3,4,8,6]

matplotlib.pyplot.scatter(x,y)

matplotlib.pyplot.show()
```
EDIT: Let me see if I understand you correctly now: You have:
```
test1 | test2 | test3
test3 |   1   |   0  |  1

test4 |   0   |   1  |  0

test5 |   1   |   1  |  0
```
Now you want to represent the above values in in a scatter plot, such that value of 1 is represented by a dot. Let's say you results are stored in a 2-D list:
```
results = [[1, 0, 1], [0, 1, 0], [1, 1, 0]]
```
We want to transform them into two variables so we are able to plot them. And I believe this code will give you what you are looking for:
```
import matplotlib
import pylab

results = [[1, 0, 1], [0, 1, 0], [1, 1, 0]]

x = []
y = []

for ind_1, sublist in enumerate(results):
    for ind_2, ele in enumerate(sublist):
        if ele == 1:
            x.append(ind_1)
            y.append(ind_2)

matplotlib.pyplot.scatter(x,y)

matplotlib.pyplot.show()
```
Notice that I do need to import pylab, and you would have play around with the axis labels. Also this feels like a work around, and there might be (probably is) a direct method to do this.


Question:
Why matplotlib does not plot? I started to learn MatPlotLib using this tutorial for beginners. Here is the first example.
```
from pylab import *
X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
C,S = np.cos(X), np.sin(X)
```
If I write these 3 lines into my python file and execute it in the command line (by typing python file_name.py), nothing happens. No error message, no plot. Does anybody know why I do not see the plot? ADDED Of course I need to use show. But even if I add the following 3 lines:
```
plot(X,C)
plot(X,S)
show()
```
it still does no generate anything. ADDED Here are the lines that I use now:
```
import pylab as p
C = [1,2,3,4]
S = [10, 20, 30, 10]
p.plot(C,S)
p.show()
```
I still have the same result (nothing).

Response: It could be a problem with the backend. What is the output of python -c 'import matplotlib; import matplotlib.pyplot; print(matplotlib.backends.backend)'? If it is the 'agg' backend, what you see is the expected behaviour as it is a non-interactive backend that does not show anything to the screen, but work with plt.savefig(...). You should switch to, e.g., TkAgg or Qt4Agg to be able to use show. You can do it in the matplotlib.rc file. @shashank: I run matplotlib both on 12.04 and 12.10 without problems. In both cases I use the Qt4Agg backend. If you don't have the matplotlibrc set, the default backend is used. I'm sure that for Precise matplotlib repo was built with TkAgg. If the Quantal version has been built with e.g. Agg, then that would explain the difference


Question:
How to disable xkcd in a matplotlib figure? You turn on xkcd style by:
```
import matplotlib.pyplot as plt
plt.xkcd()
```
But how to disable it? I try:
```
self.fig.clf()
```
But it won't work.

Response: In a nutshell, either use the context manager as @Valentin mentioned, or call plt.rcdefaults() afterwards. What's happening is that the rc parameters are being changed by plt.xkcd() (which is basically how it works). plt.xkcd() saves the current rc params returns a context manager (so that you can use a with statement) that resets them at the end. If you didn't hold on to the context manager that plt.xkcd() returns, then you can't revert to the exact same rc params that you had before. In other words, let's say you had done something like plt.rc('lines', linewidth=2, color='r') before calling plt.xkcd(). If you didn't do with plt.xkcd(): or manager = plt.xkcd(), then the state of rcParams after calling plt.rc will be lost. However, you can revert back to the default rcParams by calling plt.rcdefaults(). You just won't retain any specific changes you made before calling plt.xkcd().


Question:
Adding units to heatmap annotation in Seaborn I am trying to show a table of percentages as a heatmap in Seaborn:
```
sns.heatmap(S, annot=True, fmt=".1f", linewidths=1.0, square=1)
```
However, I'd like the percent sign to appear after each number in the heatmap annotations. The fmt flag only seems to accept number format specifiers. Is there a way to do this either within Seaborn or with some matplotlib tweaking?

Response:
You have to iterate over all text values of a heatmap and add % sign:
```
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
from matplotlib.ticker import FuncFormatter

sns.set()
fig, ax0 = plt.subplots(1,1)
data = np.array([[10.01,20.20],[-0.23,0.],[23.1049,-100.000000]])
ax = sns.heatmap(data, annot=True, fmt = '.1f', square=1, linewidth=1.)
for t in ax.texts: t.set_text(t.get_text() + " %")
plt.show()
```


Question:
Black and white boxplots in Seaborn I am trying to draw multiple black-and-white boxplots using Python's Seaborn package. By default the plots are using a color palette. I would like to draw them in solid black outline. The best I can come up with is:
```
# figure styles
sns.set_style('white')
sns.set_context('paper', font_scale=2)
plt.figure(figsize=(3, 5))
sns.set_style('ticks', {'axes.edgecolor': '0',
                        'xtick.color': '0',
                        'ytick.color': '0'})

ax = sns.boxplot(x="test1", y="test2", data=dataset, color='white', width=.5)
sns.despine(offset=5, trim=True)
sns.plt.show()
```
Which produces something like: I would like the box outlines to be black without any fill or changes in the color palette.

Response:
I was just exploring this and it seems there is another way to do this now. Basically, there are the keywords boxprops, medianprops, whiskerprops and (you guessed it) capprops, all of which are dictionaries that may be passed to the boxplot func. I choose to define them above and then unpack them for readability:
```py
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

_to_plot = pd.DataFrame(
    {
     0: np.random.normal(0, 1, 100),
     1: np.random.normal(0, 2, 100),
     2: np.random.normal(-1, 1, 100),
     3: np.random.normal(-2, 2, 100)
     }
).melt()

PROPS = {
    'boxprops':{'facecolor':'none', 'edgecolor':'red'},
    'medianprops':{'color':'green'},
    'whiskerprops':{'color':'blue'},
    'capprops':{'color':'magenta'}
}

fig, ax = plt.subplots(figsize=(10, 10))
sns.boxplot(x='variable',y='value',
            data=_to_plot,
            showfliers=False,
            linewidth=1,
            ax=ax,
            **PROPS)
```


Question:
How to change the color of a single bar if condition is True Is it possible to change only the color of a single bar in a graph made by matplotlib? Let's say I've evaluation 1 to 10 and for each one I've a graph generate when the user choice the evaluation. For each evaluation one of this boys will win. So for each graph, I would like to leave the winner bar in a different color, let's say Jim won evaluation1. Jim bar would be red, and the others blue. I have a dictionary with the values, what I tried to do was something like this:
```
for value in dictionary.keys(): # keys are the names of the boys
    if winner == value:
        facecolor = 'red'
    else:
        facecolor = 'blue'

ax.bar(ind, num, width, facecolor=facecolor)
```
Anyone knows a way of doing this?

Response:
You need to use color instead of facecolor. You can also specify color as a list instead of a scalar value. So for your example, you could have color=['r','b','b','b','b'] For example,
```
import numpy as np
import matplotlib.pyplot as plt

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

N = 5
ind = np.arange(N)
width = 0.5
vals = [1,2,3,4,5]
colors = ['r','b','b','b','b']
ax.barh(ind, vals, width, color=colors)

plt.show()
```
is a full example showing you what you want. To answer your comment:
```
colors = []
for value in dictionary.keys(): # keys are the names of the boys
    if winner == value:
        colors.append('r')
    else:
        colors.append('b')

bar(ind,num,width,color=colors)
```


Question:
AttributeError: Unknown property legend in seaborn The seaborn stripplot has a function which allows hue. Using the example from https://stanford.edu/~mwaskom/software/seaborn/generated/seaborn.stripplot.html
```
import seaborn as sns
sns.set_style("whitegrid")
tips = sns.load_dataset("tips")
ax = sns.stripplot(x=tips["total_bill"])
ax = sns.stripplot(x="sex", y="total_bill", hue="day", data=tips, jitter=True)
```
In this case, the legend is quite small, showing a different hue for each day. However, I would like to remove the legend. Normally, one includes a parameter legend=False. However, for stripplot, this appears to output an attribute error:
```
AttributeError: Unknown property legend
```
Can one remove the legend for stripplots? If so, how does one do this?

Response:
Use ax.legend_.remove() like here:
```
import seaborn as sns
import matplotlib.pylab as plt
sns.set_style("whitegrid")
tips = sns.load_dataset("tips")
ax = sns.stripplot(x="sex", y="total_bill", hue="day", data=tips, jitter=True)

# remove legend from axis 'ax'
ax.legend_.remove()

plt.show()
```


Question: Change color of specific ticks at plot with matplotlib Using matplotlib, is there an option to change the color of specific tick labels on the axis? I have a simple plot that show some values by days, and I need to mark some days as 'special' day so I want to mark these with a different color but not all ticks just some specific.

Response:
You can get a list of tick labels using ax.get_xticklabels(). This is actually a list of text objects. As a result, you can use set_color() on an element of that list to change the color:
```
import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(5,4))
ax.plot([1,2,3])

ax.get_xticklabels()[3].set_color("red")

plt.show()
```
Alternatively, you can get the current axes using plt.gca(). The below code will give the same result
```
import matplotlib.pyplot as plt

plt.figure(figsize=(5,4))
plt.plot([1, 2, 3])

plt.gca().get_xticklabels()[3].set_color("red")

plt.show()
```


Question:
Increase space between rows on FacetGrid plot I've the following code which creates the plot you can see in the picture:
```
g = sns.FacetGrid(data, col="Provincia",col_wrap=6,size=2.5)
g.map(sns.barplot, "Anio", "Diff");
g.set_axis_labels("Año", "Porcentaje de aumento");

for ax in g.axes.flat:
    _ = plt.setp(ax.get_yticklabels(), visible=True)
    _ = plt.setp(ax.get_xticklabels(), visible=False)
    _ = plt.setp(ax.get_xticklabels()[0], visible=True)
    _ = plt.setp(ax.get_xticklabels()[-1], visible=True)
```
The problem, as you can see in the picture, is that the x ticks collapse with the col name below. What is the proper way to increase this space in order to fix this?

Response:
tight layout You can use tight_layout to automatically adjust the spacings
```
g.fig.tight_layout()
```
or, if you have matplotlib.pyplot imported as plt,
```
plt.tight_layout()
```
subplots adjust You can use plt.subplots_adjust to manually set the spacings between subplots,
```
plt.subplots_adjust(hspace=0.4, wspace=0.4)
```
where hspace is the space in height, and wspace is the space width direction. gridspec keyword arguments You could also use gridspec_kws in the FacetGrid initialization,
```
g = sns.FacetGrid(data, ... , gridspec_kws={"wspace":0.4})
```
However, this can only be used if col_wrap is not set. (So it might not be an option in the particular case from the question).


Question:
Elegant way to match a string to a random color matplotlib I want to translate the labels of some data to colors for graphing with matplotlib I have a list of names ["bob", "joe", "andrew", "pete"] Is there a built in way to map these strings with color values in matplotlib? I thought about randomly creating hex values but I could end up with similar colors or non visible colors. I've tried a couple different ways of trying to create key values from the below cmap answer: this:
```
#names is a list of distinct names
cmap = plt.get_cmap('cool')
colors = cmap(np.linspace(0, 1, len(names)))
clr = {names[i]: colors[i] for i in range(len(names))}
ax.scatter(x, y, z, c=clr)
```

Response:
Choose a color map, such as viridis:
```
cmap = plt.get_cmap('viridis')
```
The colormap, cmap, is a function which can take an array of values from 0 to 1 and map them to RGBA colors. np.linspace(0, 1, len(names)) produces an array of equally spaced numbers from 0 to 1 of length len(names). Thus,
```
colors = cmap(np.linspace(0, 1, len(names)))
```
selects equally-spaced colors from the viridis color map. Note that this is not using the value of the string, it only uses the ordinal position of the string in the list to select a color. Note also that these are not random colors, this is just an easy way to generate unique colors from an arbitrary list of strings. So:
```
import numpy as np
import matplotlib.pyplot as plt

cmap = plt.get_cmap('viridis')
names = ["bob", "joe", "andrew", "pete"]
colors = cmap(np.linspace(0, 1, len(names)))
print(colors)
# [[ 0.267004  0.004874  0.329415  1.      ]
#  [ 0.190631  0.407061  0.556089  1.      ]
#  [ 0.20803   0.718701  0.472873  1.      ]
#  [ 0.993248  0.906157  0.143936  1.      ]]

x = np.linspace(0, np.pi*2, 100)
for i, (name, color) in enumerate(zip(names, colors), 1):
    plt.plot(x, np.sin(x)/i, label=name, c=color)
plt.legend()
plt.show()
```
The problem with
```
clr = {names[i]: colors[i] for i in range(len(names))}
ax.scatter(x, y, z, c=clr)
```
is that the c parameter of ax.scatter expects a sequence of RGB(A) values of the same length as x or a single color. clr is a dict, not a sequence. So if colors is the same length as x then you could use
```
ax.scatter(x, y, z, c=colors)
```


Question:
animated subplots using matplotlib I have this code. I want to add a subplot to draw the cosine function. (I do not want to create a class). The second plot should be dynamically updated as well
```
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

def data_gen():
    t = data_gen.t
    cnt = 0
    while cnt < 1000:
        cnt+=1
        t += 0.05
        yield t, np.sin(2*np.pi*t) * np.exp(-t/10.)
data_gen.t = 0

fig, ax = plt.subplots()
line, = ax.plot([], [], lw=2)
ax.set_ylim(-1.1, 1.1)
ax.set_xlim(0, 5)
ax.grid()
xdata, ydata = [], []
def run(data):
    # update the data
    t,y = data
    xdata.append(t)
    ydata.append(y)
    xmin, xmax = ax.get_xlim()

    if t >= xmax:
        ax.set_xlim(xmin, 2*xmax)
        ax.figure.canvas.draw()
    line.set_data(xdata, ydata)

    return line,

ani = animation.FuncAnimation(fig, run, data_gen, blit=True, interval=10,
    repeat=False)
plt.show()
```

Response:
Basically you can use a very similar structure as the one you have in your example. You only need to create an additional axes (subplot) and a second line object:
```
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

def data_gen():
    t = data_gen.t
    cnt = 0
    while cnt < 1000:
        cnt+=1
        t += 0.05
        y1 = np.sin(2*np.pi*t) * np.exp(-t/10.)
        y2 = np.cos(2*np.pi*t) * np.exp(-t/10.)
        # adapted the data generator to yield both sin and cos
        yield t, y1, y2

data_gen.t = 0

# create a figure with two subplots
fig, (ax1, ax2) = plt.subplots(2,1)

# intialize two line objects (one in each axes)
line1, = ax1.plot([], [], lw=2)
line2, = ax2.plot([], [], lw=2, color='r')
line = [line1, line2]

# the same axes initalizations as before (just now we do it for both of them)
for ax in [ax1, ax2]:
    ax.set_ylim(-1.1, 1.1)
    ax.set_xlim(0, 5)
    ax.grid()

# initialize the data arrays
xdata, y1data, y2data = [], [], []
def run(data):
    # update the data
    t, y1, y2 = data
    xdata.append(t)
    y1data.append(y1)
    y2data.append(y2)

    # axis limits checking. Same as before, just for both axes
    for ax in [ax1, ax2]:
        xmin, xmax = ax.get_xlim()
        if t >= xmax:
            ax.set_xlim(xmin, 2*xmax)
            ax.figure.canvas.draw()

    # update the data of both line objects
    line[0].set_data(xdata, y1data)
    line[1].set_data(xdata, y2data)

    return line

ani = animation.FuncAnimation(fig, run, data_gen, blit=True, interval=10,
    repeat=False)
plt.show()
```


Question:
Multiple legends in for-loop The following program executes fine but only one legend is displayed. How can I have all the four legends displayed? kindly see the image attached.
```
import matplotlib.pyplot as plt
dct = {'list_1' : [1,2,4,3,1],'list_2' : [2,4,5,1,2],'list_3' : [1,1,3,4,6],'list_4' : [1,1,2,2,1]}

xs = [0,1,2,3,4]

for i in [1,2,3,4]:
    plt.plot(xs,dct['list_%s' %i])
    plt.legend(['%s data' %i])

plt.show()
```

Response:
```
import matplotlib.pyplot as plt
dct = {'list_1' : [1,2,4,3,1],'list_2' : [2,4,5,1,2],'list_3' : [1,1,3,4,6],'list_4' : [1,1,2,2,1]}

xs = [0,1,2,3,4]

for i in [1,2,3,4]:
    plt.plot(xs,dct['list_%s' %i], label='%s data' % i)

plt.legend()

plt.show()
```
You are running up against the way that legend works, each time it is called it destroys the current legend and replaces it with the new one. If you only give legend a list of strings it iterates through the artists (the objects that represent the data to be drawn) in the axes until it runs out of labels (hence why your first curve is labeled as the 4th). If you include the kwarg label in the plot command, when you call legend with out any arguments, it will iterate through the artists* and generate legend entries for the artists with labels. [*] there are some exceptions on which artists it will pick up


Question:
Setting the display range suplot of errorbars in matplotlib I'm trying to plot my data using matplot lib. I have 3 separetes sets of data I want to plot in 3 subplots (I'm using this is my guidence):
```
plt.figure()

fig, axs = plt.subplots(nrows=3, ncols = 1, sharex=False)
ax1 = axs[0]
ax1.errorbar(X,Y,Err,fmt='o')
ax1.set_xscale('log')
ax1.set_yscale('log')
ax1.set_title('epsilon=1.5, kappa = 2')
plt.show()
```
However I get the x range from 1 (or 0, I'm not sure) to 100 and I want to reduce it. I tried this, by adding using:
```
ax1.xlim(0.5,13.5)
```
But I get an error: AttributeError: 'AxesSubplot' object has no attribute 'xlim' How can I change the range then?

Response:
You might want to use Axes.axis(*v, **kwargs):
```
ax1.axis(xmin=0.5,xmax=13.5)
```
From the documentation: Set/Get the axis properties If len(*v)==0, you can pass in xmin, xmax, ymin, ymax as kwargs selectively to alter just those limits without changing the others.


Question:
Plot a Single XGBoost Decision Tree I am using method on https://machinelearningmastery.com/visualize-gradient-boosting-decision-trees-xgboost-python/ to plot a XGBoost Decision Tree
```
from numpy import loadtxt
from xgboost import XGBClassifier
from xgboost import plot_tree
import matplotlib.pyplot as plt
# load data
dataset = loadtxt('pima-indians-diabetes.csv', delimiter=",")
# split data into X and y
X = dataset[:,0:8]
y = dataset[:,8]
# fit model no training data
model = XGBClassifier()
model.fit(X, y)
# plot single tree
plot_tree(model)
plt.show()
```
As I got 150 features,the plot looks quite small for all split points,how to draw a clear one or save in local place or any other ways/ideas could clearly show this ‘tree’ is quite appreciated

Response:
I had the same problem recently and the only way I found is by trying diffent figure size (it can still be bluery with big figure. For exemple, to plot the 4th tree, use:
```
fig, ax = plt.subplots(figsize=(30, 30))
xgb.plot_tree(model, num_trees=4, ax=ax)
plt.show()
```
To save it, you can do
```
plt.savefig("temp.pdf")
```
Also, each tree seperates two classes so you have as many tree as class.


Question:
Seaborn configuration hides default matplotlib [duplicate] This question already has answers here: How can I use seaborn without changing the matplotlib defaults? (2 answers) Closed 6 years ago. Seaborn provides of a handful of graphics which are very interesting for scientifical data representation. Thus I started using these Seaborn graphics interspersed with other customized matplotlib plots. The problem is that once I do:
```
import seaborn as sb
```
This import seems to set the graphic parameters for seaborn globally and then all matplotlib graphics below the import get the seaborn parameters (they get a grey background, linewithd changes, etc, etc). In SO there is an answer explaining how to produce seaborn plots with matplotlib configuration, but what I want is to keep the matplotlib configuration parameters unaltered when using both libraries together and at the same time be able to produce, when needed, original seaborn plots.

Response:
If you never want to use the seaborn style, but do want some of the seaborn functions, you can import seaborn using this following line (documentation):
```
import seaborn.apionly as sns
```
If you want to produce some plots with the seaborn style and some without, in the same script, you can turn the seaborn style off using the seaborn.reset_orig function. It seems that doing the apionly import essentially sets reset_orig automatically on import, so its up to you which is most useful in your use case. Here's an example of switching between matplotlib defaults and seaborn:
```
import matplotlib.pyplot as plt
import matplotlib
import numpy as np

# a simple plot function we can reuse (taken from the seaborn tutorial)
def sinplot(flip=1):
    x = np.linspace(0, 14, 100)
    for i in range(1, 7):
        plt.plot(x, np.sin(x + i * .5) * (7 - i) * flip)

sinplot()

# this will have the matplotlib defaults
plt.savefig('seaborn-off.png')
plt.clf()

# now import seaborn
import seaborn as sns

sinplot()

# this will have the seaborn style
plt.savefig('seaborn-on.png')
plt.clf()

# reset rc params to defaults
sns.reset_orig()

sinplot()

# this should look the same as the first plot (seaborn-off.png)
plt.savefig('seaborn-offagain.png')
```
which produces the following three plots: seaborn-off.png: seaborn-on.png: seaborn-offagain.png:


Question:
Plot 2-dimensional NumPy array using specific columns I have a 2D numpy array that's created like this:
```
data = np.empty((number_of_elements, 7))
```
Each row with 7 (or whatever) floats represents an object's properties. The first two for example are the x and y position of the object, the others are various properties that could even be used to apply color information to the plot. I want to do a scatter plot from data, so that if p = data[i], an object is plotted as a point with p[:2] as its 2D position and with say p[2:4] as a color information (the length of that vector should determine a color for the point). Other columns should not matter to the plot at all. How should I go about this?

Response:
Setting up a basic matplotlib figure is easy:
```
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
```
Picking off the columns for x, y and color might look something like this:
```
N = 100
data = np.random.random((N, 7))
x = data[:,0]
y = data[:,1]
points = data[:,2:4]
# color is the length of each vector in `points`
color = np.sqrt((points**2).sum(axis = 1))/np.sqrt(2.0)
rgb = plt.get_cmap('jet')(color)
```
The last line retrieves the jet colormap and maps each of the float values (between 0 and 1) in the array color to a 3-tuple RGB value. There is a list of colormaps to choose from here. There is also a way to define custom colormaps. Making a scatter plot is now straight-forward:
```
ax.scatter(x, y, color = rgb)
plt.show()
# plt.savefig('/tmp/out.png')    # to save the figure to a file
```


Question:
How to set space between the axis and the label My code:
```
#importing required libraries
import numpy as np
from matplotlib.patches import Polygon
import matplotlib.pyplot as plt

#plotting data

def func(x):
    return (x-3)*(x+2)*(3*x+5)+25
a,b=2,9
x=np.linspace(0,10,30)
y=func(x)
fig,ax=plt.subplots(1,1,dpi=135)
ax.plot(x,y,linewidth=2.5,color='c')
ix=np.linspace(a,b)
iy=func(ix)
verts=[(a,0),*zip(ix,iy),(b,0)]
poly=Polygon(verts,facecolor='0.7',edgecolor='0.9')
ax.add_patch(poly)
ax.set_ylim(bottom=0)
ax.text(6.5,150,r'$\int_a^b f(x)$',horizontalalignment='center',fontsize=15)
ax.set_xlabel('X')
ax.set_ylabel('Y',rotation=0)
ax.set_xticks((a,b))
ax.set_xticklabels(('a','b'))
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
ax.xaxis.set_ticks_position('bottom')
ax.set_yticks([])
plt.show()
```
The above code gives: My Question: So as you have saw the above plot the ylabel 'Y' is touching with the y-axis and there is space between the xlabel 'X' and x-axis How can I set space between the axis and the label(like there is a space between xlabel and x-axis)? My attempt: In the above code I commented set_ylabel() method and tried text() method
```
#ax.set_ylabel('Y',rotation=0)
fig.text(0.1,0.5,'Y')
#this code creating a little space between y label and y-axis but I want the same amount of space that is between x label an x axis
```
Expected output:

Response:
You can set bounding by using labelpad argument like this
```
ax.set_ylabel('Y', rotation=0, labelpad=10)
```
also you can add space after 'Y ' label in set_ylabel line as following
```
ax.set_ylabel('Y ',rotation=0)
```
Note: As you mentioned you want the same spaces between both axis labels so you can set 'X' label using:
```
ax.text(max(x)/2, -(max(y)/10),'X')
```
and 'Y' label using:
```
ax.text(-(max(x)/10), max(y)/2,'Y')
```


Question:
Automatically setting y-axis limits for bar graph using matplotlib Here's an example of graphing large values.
```py
import matplotlib.pyplot as plt
x = [1,2,3,4,5]
y = [1000, 1002, 1001, 1003, 1005]
plt.bar(x,y)
plt.show()
```
The y-axis starts at 0, so the bars all look equal. I know you can use plt.ylim to manually set the limits, but is there a way for matplotlib to automatically (and smartly) set the limits to reasonable values (like 998-1008), and also perhaps show an axis break?

Response:
A little bit of simple algebra will help fix the limits:
```
import matplotlib.pyplot as plt
import math
x = [1,2,3,4,5]
y = [1000, 1002, 1001, 1003, 1005]
low = min(y)
high = max(y)
plt.ylim([math.ceil(low-0.5*(high-low)), math.ceil(high+0.5*(high-low))])
plt.bar(x,y)
plt.show()
```
In this way, you are able to find the difference between your y-values and use them to set the scale along the y-axis. I used math.ceil (as opposed to math.floor) in order to obtain the values you specified and ensure integers. As far as an axis break goes, I'd suggest looking at this example.


Question:
Plotting histograms against classes in pandas / matplotlib Is there a idiomatic way to plot the histogram of a feature for two classes? In pandas, I basically want
```
df.feature[df.class == 0].hist()
df.feature[df.class == 1].hist()
```
To be in the same plot. I could do
```
df.feature.hist(by=df.class)
```
but that gives me two separate plots. This seems to be a common task so I would imagine there to be an idiomatic way to do this. Of course I could manipulate the histograms manually to fit next to each other but usually pandas does that quite nicely. Basically I want this matplotlib example in one line of pandas: http://matplotlib.org/examples/pylab_examples/barchart_demo.html I thought I was missing something, but maybe it is not possible (yet).

Response:
How about df.groupby("class").feature.hist()? To see overlapping distributions you'll probably need to pass alpha=0.4 to hist(). Alternatively, I'd be tempted to use a kernel density estimate instead of a histogram with df.groupby("class").feature.plot(kind='kde'). As an example, I plotted the iris dataset's classes using:
```
iris.groupby("Name").PetalWidth.plot(kind='kde', ax=axs[1])
iris.groupby("Name").PetalWidth.hist(alpha=0.4, ax=axs[0])
```


Question:
Matplotlib does not display hatching when rendering to pdf I am attempting to use the hatching feature in matplotlib, which works fine when displaying to screen. However when I save the figure to pdf format, the hatch marks are not rendered:
```
import matplotlib
import matplotlib.pyplot as plt
import numpy as np

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

plt.figure()
plt.fill(x,np.sin(x),color='blue',alpha=0.5,hatch='/')
plt.show()
plt.savefig('./test.pdf',format='pdf')
```
I am using matplotlib 1.0.1 in pylab on OS X 10.6.6. This may be a platform specific issue having to do with the backend renderer, but I'm not sure. Any suggestions would be most appreciated.

Response: TL;DR: use alpha=.99 to render hatches when exporting in PDF It's nearly 2020 and the bug still exists when using plt.bar(). When rendering in PNG, everything is rendered properly. However, PDF export has a glitch when rendering hatches. Hatches are not visible, sometimes visible when zooming-in/out (sometimes not when tested on different computers), it is not clear where the bug comes from. We realized it's linked with the alpha option. When using alpha=.5, the color is 50% visible, as well as hatches (50% visible as well). Good step, we have almost visible hatches. Therefore, let's just try with alpha=.99 so that everything is nearly 100% visible. It works! Houray! In our workaround, no need to duplicate lines like in previous answer. Keep the color option as it is and just set alpha=.99.


Question: Removing axis margins in 3D plot I spent last few days trying to find a way to remove tiny margins from axis in a 3D plot. I tried ax.margins(0) and ax.autoscale_view('tight') and other approaches, but these small margins are still there. In particular, I don't like that the bar histograms are elevated, i.e., their bottom is not at the zero level -- see example image. ![unwanted margins on all axis][1] In gnuplot, I would use "set xyplane at 0". In matplotlib, since there are margins on every axis on both sides, it would be great to be able to control each of them. Edit: HYRY's solution below works well, but the 'X' axis gets a grid line drawn over it at Y=0:

Response:
There is not property or method that can modify this margins. You need to patch the source code. Here is an example:
```
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
###patch start###
from mpl_toolkits.mplot3d.axis3d import Axis
if not hasattr(Axis, "_get_coord_info_old"):
    def _get_coord_info_new(self, renderer):
        mins, maxs, centers, deltas, tc, highs = self._get_coord_info_old(renderer)
        mins += deltas / 4
        maxs -= deltas / 4
        return mins, maxs, centers, deltas, tc, highs
    Axis._get_coord_info_old = Axis._get_coord_info
    Axis._get_coord_info = _get_coord_info_new
###patch end###

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
for c, z in zip(['r', 'g', 'b', 'y'], [30, 20, 10, 0]):
    xs = np.arange(20)
    ys = np.random.rand(20)

    # You can provide either a single color or an array. To demonstrate this,
    # the first bar of each set will be colored cyan.
    cs = [c] * len(xs)
    cs[0] = 'c'
    ax.bar(xs, ys, zs=z, zdir='y', color=cs, alpha=0.8)

ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')

plt.show()
```
The result is: Edit To change the color of the grid lines:
```
for axis in (ax.xaxis, ax.yaxis, ax.zaxis):
    axis._axinfo['grid']['color']  = 0.7, 1.0, 0.7, 1.0
```
Edit2 Set X & Y lim:
```
ax.set_ylim3d(-1, 31)
ax.set_xlim3d(-1, 21)
```


Question:
Multiple figures in a single window I want to create a function which plot on screen a set of figures in a single window. By now I write this code:
```
import pylab as pl

def plot_figures(figures):
    """Plot a dictionary of figures.

    Parameters
    ----------
    figures : <title, figure> dictionary

    """
    for title in figures:
        pl.figure()
        pl.imshow(figures[title])
        pl.gray()
        pl.title(title)
        pl.axis('off')
```
It works perfectly but I would like to have the option for plotting all the figures in single window. And this code doesn't. I read something about subplot but it looks quite tricky.

Response:
You can define a function based on the subplots command (note the s at the end, different from the subplot command pointed by urinieto) of matplotlib.pyplot. Below is an example of such a function, based on yours, allowing to plot multiples axes in a figure. You can define the number of rows and columns you want in the figure layout.
```
def plot_figures(figures, nrows = 1, ncols=1):
    """Plot a dictionary of figures.

    Parameters
    ----------
    figures : <title, figure> dictionary
    ncols : number of columns of subplots wanted in the display
    nrows : number of rows of subplots wanted in the figure
    """

    fig, axeslist = plt.subplots(ncols=ncols, nrows=nrows)
    for ind,title in enumerate(figures):
        axeslist.ravel()[ind].imshow(figures[title], cmap=plt.gray())
        axeslist.ravel()[ind].set_title(title)
        axeslist.ravel()[ind].set_axis_off()
    plt.tight_layout() # optional
```
Basically, the function creates a number of axes in the figures, according to the number of rows (nrows) and columns (ncols) you want, and then iterates over the list of axis to plot your images and adds the title for each of them. Note that if you only have one image in your dictionary, your previous syntax plot_figures(figures) will work since nrows and ncols are set to 1 by default. An example of what you can obtain:
```
import matplotlib.pyplot as plt
import numpy as np

# generation of a dictionary of (title, images)
number_of_im = 6
figures = {'im'+str(i): np.random.randn(100, 100) for i in range(number_of_im)}

# plot of the images in a figure, with 2 rows and 3 columns
plot_figures(figures, 2, 3)
```


Question:
Running matplotlib in tkinter I have this beautiful sphere I made in matplotlib. How would I go about putting it in a tkinter frame widget? It'd be nice to be able to integrate it into an existing tkinter GUI. Also is it possible to rid of the menu bar below the display? I have no need to save the output or zoom, so it's useless to me.
```
from mpl_toolkits.mplot3d import  axes3d,Axes3D
import matplotlib.pyplot as plt
from matplotlib import cm
import numpy as np

fig = plt.figure()
ax = Axes3D(fig) #<-- Note the difference from your original code..

u = np.linspace(0, 2 * np.pi, 100)
v = np.linspace(0, np.pi, 100)

x = 10 * np.outer(np.cos(u), np.sin(v))
y = 10 * np.outer(np.sin(u), np.sin(v))
z = 10 * np.outer(np.ones(np.size(u)), np.cos(v))

ax.plot_surface(x, y, z,  rstride=4, cstride=4, color='lightgreen',linewidth=0)
#,antialiased=False
#cmap=cm.jet
plt.show()
```

Response: Have a look at the examples for embedding plots in a tk GUI, it should be enough to get you started in the right direction. user_interfaces example code: embedding_in_tk.py user_interfaces example code: embedding_in_tk2.py As for removing the toolbar, it's a case of not adding it when you are embedding plots in a GUI. If you are using matplotlib.pyplot the toolbar will be created automatically for every figure. If you are writing your own user interface code, you can add the toolbar as a widget.


Question:
Indicating the statistically significant difference in bar graph I use a bar graph to indicate the data of each group. Some of these bars differ significantly from each other. How can I indicate the significant difference in the bar plot?
```
import numpy as np
import matplotlib.pyplot as plt
menMeans   = (5, 15, 30, 40)
menStd     = (2, 3, 4, 5)
ind = np.arange(4)    # the x locations for the groups
width=0.35
p1 = plt.bar(ind, menMeans, width=width, color='r', yerr=menStd)
plt.xticks(ind+width/2., ('A', 'B', 'C', 'D') )
```
I am aiming for

Response:
The answer above inspired me to write a small but flexible function myself:
```
def barplot_annotate_brackets(num1, num2, data, center, height, yerr=None, dh=.05, barh=.05, fs=None, maxasterix=None):
    """
    Annotate barplot with p-values.

    :param num1: number of left bar to put bracket over
    :param num2: number of right bar to put bracket over
    :param data: string to write or number for generating asterixes
    :param center: centers of all bars (like plt.bar() input)
    :param height: heights of all bars (like plt.bar() input)
    :param yerr: yerrs of all bars (like plt.bar() input)
    :param dh: height offset over bar / bar + yerr in axes coordinates (0 to 1)
    :param barh: bar height in axes coordinates (0 to 1)
    :param fs: font size
    :param maxasterix: maximum number of asterixes to write (for very small p-values)
    """

    if type(data) is str:
        text = data
    else:
        # * is p < 0.05
        # ** is p < 0.005
        # *** is p < 0.0005
        # etc.
        text = ''
        p = .05

        while data < p:
            text += '*'
            p /= 10.

            if maxasterix and len(text) == maxasterix:
                break

        if len(text) == 0:
            text = 'n. s.'

    lx, ly = center[num1], height[num1]
    rx, ry = center[num2], height[num2]

    if yerr:
        ly += yerr[num1]
        ry += yerr[num2]

    ax_y0, ax_y1 = plt.gca().get_ylim()
    dh *= (ax_y1 - ax_y0)
    barh *= (ax_y1 - ax_y0)

    y = max(ly, ry) + dh

    barx = [lx, lx, rx, rx]
    bary = [y, y+barh, y+barh, y]
    mid = ((lx+rx)/2, y+barh)

    plt.plot(barx, bary, c='black')

    kwargs = dict(ha='center', va='bottom')
    if fs is not None:
        kwargs['fontsize'] = fs

    plt.text(*mid, text, **kwargs)
```
which allows me to get some nice annotations relatively simple, e.g.:
```
heights = [1.8, 2, 3]
bars = np.arange(len(heights))

plt.figure()
plt.bar(bars, heights, align='center')
plt.ylim(0, 5)
barplot_annotate_brackets(0, 1, .1, bars, heights)
barplot_annotate_brackets(1, 2, .001, bars, heights)
barplot_annotate_brackets(0, 2, 'p < 0.0075', bars, heights, dh=.2)
```


Question:
Python/Matplotlib - How to put text in the corner of equal aspect figure I would like to put text in the right bottom corner of equal aspect figure. I set the position relative to the figure by ax.transAxes, but I have to define the relative coordinate value manually depending on height scales of each figures. What would be a good way to know axes height scale and the correct text position within the script?
```
ax = plt.subplot(2,1,1)
 ax.plot([1,2,3],[1,2,3])
 ax.set_aspect('equal')
 ax.text(1,-0.15, 'text', transform=ax.transAxes, ha='right', fontsize=16)
 print ax.get_position().height

 ax = plt.subplot(2,1,2)
 ax.plot([10,20,30],[1,2,3])
 ax.set_aspect('equal')
 ax.text(1,-0.15, 'text', transform=ax.transAxes, ha='right', fontsize=16)
 print ax.get_position().height
```

Response:
Use annotate. In fact, I hardly ever use text. Even when I want to place things in data coordinates, I usually want to offset it by some fixed distance in points, which is much easier with annotate. As a quick example:
```
import matplotlib.pyplot as plt

fig, axes = plt.subplots(nrows=2, subplot_kw=dict(aspect=1))

axes[0].plot(range(1, 4))
axes[1].plot(range(10, 40, 10), range(1, 4))

for ax in axes:
    ax.annotate('Test', xy=(1, 0), xycoords='axes fraction', fontsize=16,
                horizontalalignment='right', verticalalignment='bottom')
plt.show()
```
If you'd like it slightly offset from the corner, you can specify an offset through the xytext kwarg (and textcoords to control how the values of xytext are interpreted). I'm also using the ha and va abbreviations for horizontalalignment and verticalalignment here:
```
import matplotlib.pyplot as plt

fig, axes = plt.subplots(nrows=2, subplot_kw=dict(aspect=1))

axes[0].plot(range(1, 4))
axes[1].plot(range(10, 40, 10), range(1, 4))

for ax in axes:
    ax.annotate('Test', xy=(1, 0), xycoords='axes fraction', fontsize=16,
                xytext=(-5, 5), textcoords='offset points',
                ha='right', va='bottom')
plt.show()
```
If you're trying to place it below the axes, you can use the offset to place it a set distance below in points:
```
import matplotlib.pyplot as plt

fig, axes = plt.subplots(nrows=2, subplot_kw=dict(aspect=1))

axes[0].plot(range(1, 4))
axes[1].plot(range(10, 40, 10), range(1, 4))

for ax in axes:
    ax.annotate('Test', xy=(1, 0), xycoords='axes fraction', fontsize=16,
                xytext=(0, -15), textcoords='offset points',
                ha='right', va='top')
plt.show()
```
Also have a look at the Matplotlib annotation guide for more information.


Question:
Diagonal tick labels I am plotting a bar chart in python using matplotlib.pyplot. The chart will contain a large number of bars, and each bar has its own label. Thus, the labels overlap, and they are no more readable. I would like that the label are displayed diagonally so that they do not overlab, such as in this image. This is my code:
```
import matplotlib.pyplot as plt
N =100
menMeans = range(N)
ind = range(N)
ticks = ind
fig = plt.figure()
ax = fig.add_subplot(111)
rects1 = ax.bar(ind, menMeans, align = 'center')
ax.set_xticks(ind)
ax.set_xticklabels( range(N) )
plt.show()
```
How can the labels be displayed diagonally?

Response:
Instead of using set_xticks or set_xticklabels, which are both officially discouraged, you can just use the rotation parameter to xticks:
```
plt.xticks(rotation=45, ha="right")
```
This way you can specify the tick labels' rotation while letting matplotlib take care of their frequency/spacing for you. Note that the use of ha="right" to right-align the label text doesn't matter if your labels are all short (and you may want to remove it in that case), but is important if your labels are long and of variable length - it ensures that the end of the tick label is directly below the tick it's labelling, and prevents labels from being inconsistently spaced or even overlapping. A full working example, based on the code in the question:
```
import matplotlib.pyplot as plt
N =100
menMeans = range(N)
ind = range(N)
ticks = ind
fig = plt.figure()
ax = fig.add_subplot(111)
rects1 = ax.bar(ind, menMeans, align = 'center')
plt.xticks(rotation=45, ha="right")
plt.show()
```
Output:


Question: Combine picture and plot with Python Matplotlib I have a plot which has timestamps on the x-axis and some signal data on the y-axis. As a documentation I want to put timestamped pictures in relation to specific points in the plot. Is it possible to draw a line in a plot to a picture in a sequence of pictures below the plot?

Response:
This demo from the matplotlib gallery shows how to insert pictures, draw lines to them, etc. I'll post the image from the gallery, and you can follow the link to see the code. And here's the code (from version 2.1.2):
```
import matplotlib.pyplot as plt
import numpy as np

from matplotlib.patches import Circle
from matplotlib.offsetbox import (TextArea, DrawingArea, OffsetImage,
                                  AnnotationBbox)
from matplotlib.cbook import get_sample_data

if 1:
    fig, ax = plt.subplots()

    # Define a 1st position to annotate (display it with a marker)
    xy = (0.5, 0.7)
    ax.plot(xy[0], xy[1], ".r")

    # Annotate the 1st position with a text box ('Test 1')
    offsetbox = TextArea("Test 1", minimumdescent=False)

    ab = AnnotationBbox(offsetbox, xy,
                        xybox=(-20, 40),
                        xycoords='data',
                        boxcoords="offset points",
                        arrowprops=dict(arrowstyle="->"))
    ax.add_artist(ab)

    # Annotate the 1st position with another text box ('Test')
    offsetbox = TextArea("Test", minimumdescent=False)

    ab = AnnotationBbox(offsetbox, xy,
                        xybox=(1.02, xy[1]),
                        xycoords='data',
                        boxcoords=("axes fraction", "data"),
                        box_alignment=(0., 0.5),
                        arrowprops=dict(arrowstyle="->"))
    ax.add_artist(ab)

    # Define a 2nd position to annotate (don't display with a marker this time)
    xy = [0.3, 0.55]

    # Annotate the 2nd position with a circle patch
    da = DrawingArea(20, 20, 0, 0)
    p = Circle((10, 10), 10)
    da.add_artist(p)

    ab = AnnotationBbox(da, xy,
                        xybox=(1.02, xy[1]),
                        xycoords='data',
                        boxcoords=("axes fraction", "data"),
                        box_alignment=(0., 0.5),
                        arrowprops=dict(arrowstyle="->"))

    ax.add_artist(ab)

    # Annotate the 2nd position with an image (a generated array of pixels)
    arr = np.arange(100).reshape((10, 10))
    im = OffsetImage(arr, zoom=2)
    im.image.axes = ax

    ab = AnnotationBbox(im, xy,
                        xybox=(-50., 50.),
                        xycoords='data',
                        boxcoords="offset points",
                        pad=0.3,
                        arrowprops=dict(arrowstyle="->"))

    ax.add_artist(ab)

    # Annotate the 2nd position with another image (a Grace Hopper portrait)
    fn = get_sample_data("grace_hopper.png", asfileobj=False)
    arr_img = plt.imread(fn, format='png')

    imagebox = OffsetImage(arr_img, zoom=0.2)
    imagebox.image.axes = ax

    ab = AnnotationBbox(imagebox, xy,
                        xybox=(120., -80.),
                        xycoords='data',
                        boxcoords="offset points",
                        pad=0.5,
                        arrowprops=dict(
                            arrowstyle="->",
                            connectionstyle="angle,angleA=0,angleB=90,rad=3")
                        )

    ax.add_artist(ab)

    # Fix the display limits to see everything
    ax.set_xlim(0, 1)
    ax.set_ylim(0, 1)

    plt.show()
```


Question: Remove Seaborn barplot legend title I use seaborn to plot a grouped bar plot as in https://seaborn.pydata.org/examples/factorplot_bars.html Giving me: https://seaborn.pydata.org/_images/factorplot_bars.png there is a title (sex) on the legend which I would like to remove. How could I achieve that?

Response:
This may be a hacky solution but it works: if you tell Seaborn to leave it off at the time of plotting and then add it back it doesn't have the legend title:
```
g = sns.factorplot(x='Age Group',y='ED',hue='Became Member',col='Coverage Type',
                   col_wrap=3,data=gdf,kind='bar',ci=None,legend=False,palette='muted')
#                                                         ^^^^^^^^^^^^
plt.suptitle('ED Visit Rate per 1,000 Members per Year',size=16)
plt.legend(loc='best')
plt.subplots_adjust(top=.925)
plt.show()
```
Example result:


Question: Draw arrow outside plot in Matplotlib I have the following gridded plot, and would like to draw an arrow (shown in blue using MS paint). How can I do it through matplotlib? I do not know of any command to do it.

Response:
```
import matplotlib.pyplot as plt

fg = plt.figure(1);
fg.clf();
ax = fg.add_subplot(1,1,1)
ax.annotate('', xy=(0, -0.1), xycoords='axes fraction', xytext=(1, -0.1),
            arrowprops=dict(arrowstyle="<->", color='b'))
ax.grid(True)
fg.canvas.draw()
```
gives


Question:
seaborn boxplot: Change color and shape of mean Simple question that I cannot seem to find the answer to. How do I change the color and shape of the mean indicator in a Seaborn Boxplot? It defaults to a Green Triangle and it generally difficult to see. I've tried to find the answer in both the seaborn documentation, as well as the matplotlib documentation. There is also a related question on stackoverflow where someone asked how to change around colors related to the seaborn boxplots and was able to change everything except for the mean indicator.
```
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

data = [[np.random.rand(100)] for i in range(3)]

sns.boxplot(data=data, showmeans=True)

plt.show()
```

Response:
The keyword argument you are looking for is meanprops. It is in the matplotlib boxplot documentation under "other parameters":
```
import seaborn as sns

data = [[np.random.rand(100)] for i in range(3)]

sns.boxplot(data=data, showmeans=True,
            meanprops={"marker":"s","markerfacecolor":"white", "markeredgecolor":"blue"})

plt.show()
```


Question:
Setting axis labels for histogram pandas I'm fairly new to this, so there might be a very obvious answer to this. My apologies! I'm plotting two histograms via a groubpy. I'd like my subplots to each have the same x and y labels and a common title. I understood that sharex=True would do the trick, but apparently not if I set the axis only after the df.hist. I've tried various versions of setting the xlabels and am lost now.
```
import pylab as pl
from pandas import *

histo_survived = df.groupby('Survived').hist(column='Age', sharex=True, sharey=True)
pl.title("Histogram of Ages")
pl.xlabel("Age")
pl.ylabel("Individuals")
```
So what I end up with is labels only for the subplot.
```
Out: <matplotlib.text.Text at 0x11a27ead0>
```
Any idea on how to solve this? (Have to use pandas/python.)

Response:
Labels are properties of axes objects, that needs to be set on each of them. Here's an example that worked for me:
```
frame = pd.DataFrame([np.random.rand(20), np.sign(np.random.rand(20) - 0.5)]).T
frame.columns = ['Age', 'Survived']

# Note that you can let the hist function do the groupby
# the function hist returns the list of axes created
axarr = frame.hist(column='Age', by = 'Survived', sharex=True, sharey=True, layout = (2, 1))

for ax in axarr.flatten():
    ax.set_xlabel("Age")
    ax.set_ylabel("Individuals")
```


Question:
How do I plot hatched bars using pandas? I am trying to achieve differentiation by hatch pattern instead of by (just) colour. How do I do it using pandas? It's possible in matplotlib, by passing the hatch optional argument as discussed here. I know I can also pass that option to a pandas plot, but I don't know how to tell it to use a different hatch pattern for each DataFrame column.
```
df = pd.DataFrame(rand(10, 4), columns=['a', 'b', 'c', 'd'])
df.plot(kind='bar', hatch='/');
```
For colours, there is the colormap option described here. Is there something similar for hatching? Or can I maybe set it manually by modifying the Axes object returned by plot?

Response:
Plot the grouped bars with pandas.DataFrame.plot, and then iterate through the bar patches, to add the hatches. Tested in python 3.11.4, pandas 2.1.0, matplotlib 3.7.2
```py
import pandas as pd

df = pd.DataFrame(np.random.rand(10, 4), columns=['a', 'b', 'c', 'd'])

ax = df.plot(kind='bar', legend=False, figsize=(10, 6), rot=0, width=0.8)

bars = ax.patches
hatches = ''.join(h*len(df) for h in 'x/O.')

for bar, hatch in zip(bars, hatches):
    bar.set_hatch(hatch)

ax.legend(loc='lower center', ncol=4, bbox_to_anchor=(0.5, -0.15))
```


Question:
colored wireframe plot in matplotlib I am trying to color a wireframe plot according to the z-value. I can't find any code examples on the internet. Here is an example of a surface plot that has the colors I want and a wireframe plot where I can't manage to get the colors on the lines:
```
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
import matplotlib.pyplot as plt

# some numbers for the data
P=12000 #W
Q=1     #kg/s
DT=3    #K
cp=4169.32  #J/kgK

dDT=np.logspace(-2,0,20,endpoint=True)
dQ=Q*np.logspace(-3,-1,20,endpoint=True)

# the plotting data
m1,m2=np.meshgrid(dDT,dQ)
err=cp*np.sqrt((m1*Q)**2+(m2*DT)**2)/P

# the wiremesh plot that i need fixed
fig=plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_wireframe(m1, m2, err, color=err/err.max(),cmap='jet')
ax.set_xlabel('dDT')
ax.set_ylabel('DQ')
ax.set_zlabel('relative error')

# the surface plot that has the colors i want
fig = plt.figure()
ax = fig.gca(projection='3d')

surf = ax.plot_surface(m1, m2, err,rstride=1,  cstride=1, cmap=cm.jet,
    linewidth=0.1, antialiased=False)

fig.colorbar(surf, shrink=0.5, aspect=5)

ax.set_xlabel('dDT')
ax.set_ylabel('DQ')
ax.set_zlabel('relative error')
plt.show()
```
Thank you for any help!

Response:
When you use plot_wireframe, each line can only have one color. Instead, you can use plot_surface. To get plot_surface to set the edgecolors, you need to give it facecolors. Then you can set the alpha of facecolors to zero.
```
from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt
from matplotlib import cm

X, Y, Z = axes3d.get_test_data(0.2)

# Normalize to [0,1]
norm = plt.Normalize(Z.min(), Z.max())
colors = cm.viridis(norm(Z))
rcount, ccount, _ = colors.shape

fig = plt.figure()
ax = fig.add_subplot(projection='3d')
surf = ax.plot_surface(X, Y, Z, rcount=rcount, ccount=ccount,
                       facecolors=colors, shade=False)
surf.set_facecolor((0,0,0,0))
plt.show()
```


Question:
remove italics in latex subscript in matplotlib I would like to remove the italics font that appears when I use subscripts in labels. For example, the "Teff" in the x-label has "eff" in italics. I would like latex not render it in such a way. Generally, in latex this can be achieved with the \rm{} command. However, that does not work in matplotlib. Please help.
```
import numpy as np
import matplotlib.pyplot as plt

x = np.arange(10)
y = x

plt.plot(x,y,'ro')
plt.xlabel('Primary T$_{eff}$')
```

Response:
I have encountered this problem many times and it can be solved with this trick
```
plt.xlabel(r'Primary T$_{\rm eff}$')
```


Question: Changing matshow xticklabel position from top to bottom of the figure I'm using matshow() in matplotlib and the figures generated has the xticklabels on top by default. Is there a way to put the xticklabels on the bottom instead? Appreciate any help with this. /M

Response:
Try doing the following to adjust the x ticks positions:
```
ax.xaxis.set_ticks_position('bottom')
```
Similarly, for the y ticks:
```
ax.yaxis.set_ticks_position('left')
```


Question:
draw a border around subplots in matplotlib Anyone know how to draw a border around an individual subplot within a figure in matplotlib? I'm using pyplot. eg:
```
import matplotlib.pyplot as plt
f = plt.figure()
ax1 = f.add_subplot(211)
ax2 = f.add_subplot(212)
# ax1.set_edgecolor('black')
```
..but Axes objects have no 'edgecolor', and I can't seem to find a way to outline the plot from the figure level either. I'm actually wrapping mpl code and adding a wx UI with controls that I would like to have context depending on which subplot is selected. i.e. User clicks on subplot within figure canvas -- subplot is 'selected' (has an outline drawn around it, ideally sawtooth) -- GUI updates to present controls to modify that specific subplot.

Response:
You essentially want to draw outside of the axes, right? I adapted this from here. It would need clean up as I used some hard-coded "fudge-factors" in there.
```
#!/usr/bin/env python
from pylab import *

def f(t):
    s1 = cos(2*pi*t)
    e1 = exp(-t)
    return multiply(s1,e1)

t1 = arange(0.0, 5.0, 0.1)
t2 = arange(0.0, 5.0, 0.02)
t3 = arange(0.0, 2.0, 0.01)

figure(figsize=(4, 4))
sub1 = subplot(211)
l = plot(t1, f(t1), 'bo', t2, f(t2), 'k--', markerfacecolor='green')
grid(True)
title('A tale of 2 subplots')
ylabel('Damped oscillation')

## I ADDED THIS
autoAxis = sub1.axis()
rec = Rectangle((autoAxis[0]-0.7,autoAxis[2]-0.2),(autoAxis[1]-autoAxis[0])+1,(autoAxis[3]-autoAxis[2])+0.4,fill=False,lw=2)
rec = sub1.add_patch(rec)
rec.set_clip_on(False)

subplot(212)
plot(t3, cos(2*pi*t3), 'r.')
grid(True)
xlabel('time (s)')
ylabel('Undamped')

savefig('test.png')
```
Produces:


Question:
matplotlib scatterplot x axis labels When I'm adding the c option to a scatterplot in matplotlib, the x axis labels dissapear. Here's an example: https://github.com/Kornel/scatterplot-matplotlib/blob/master/Scatter%20plot%20x%20axis%20labels.ipynb Here's the same example as in the notebook:
```
import pandas as pd
import matplotlib.pyplot as plt

test_df = pd.DataFrame({
        "X": [1, 2, 3, 4],
        "Y": [5, 4, 2, 1],
        "C": [1, 2, 3, 4]
    })
```
Now compare the result of:
```
test_df.plot(kind="scatter", x="X", y="Y", s=50);
```
To:
```
test_df.plot(kind="scatter", x="X", y="Y", c="C");
```
Where are the x axis labels? Is this a feature I'm missing? Pandas version: 0.18.1 Matplotlib: 1.5.3 Python: 3.5.2 EDIT: The solution as pointed out by @Kewl is to call plt.subplots and specify the axes:
```
fig, ax = plt.subplots()
test_df.plot(kind="scatter", x="X", y="Y", s=50, c="C", cmap="plasma", ax=ax);
```
gives P.S. It looks like a jupyter issue, the label is fine when called without a jupyter notebook

Response:
That looks like a strange bug with pandas plotting to me! Here's a way around it:
```
fig, ax = plt.subplots()
df.plot(kind='scatter',x='X', y='Y', c='C', ax=ax)
ax.set_xlabel("X")
plt.show()
```
This will give you the graph you expect:


Question: Setting the size of the plotting canvas in Matplotlib I would like Matplotlib/Pyplot to generate plots with a consistent canvas size. That is, the figures can well have different sizes to accomodate the axis descriptions, but the plotting area (the rectangle within which the curves are drawn) should always have the same size. Is there a simple way to achieve that? The option figsize of pyplot.figure() seems to set the overall size of the figure, not that of the canvas, so I get a different canvas size whenever the axis description occupies more or less space.

Response:
This is one of my biggest frustrations with Matplotlib. I often work with raster data where for example i want to add a colormap, legend and some title. Any simple example from the matplotlib gallery doing so will result in a different resolution and therefore resampled data. Especially when doing image analysis you dont want any (unwanted) resampling. Here is what i usually do, although i would love to know if there are simpler or better ways. Lets start with loading a picture and outputting it just as it is with the same resolution:
```
import matplotlib.pyplot as plt
import urllib2

# load the image
img = plt.imread(urllib2.urlopen('http://upload.wikimedia.org/wikipedia/en/thumb/5/56/Matplotlib_logo.svg/500px-Matplotlib_logo.svg.png'))

# get the dimensions
ypixels, xpixels, bands = img.shape

# get the size in inches
dpi = 72.
xinch = xpixels / dpi
yinch = ypixels / dpi

# plot and save in the same size as the original
fig = plt.figure(figsize=(xinch,yinch))

ax = plt.axes([0., 0., 1., 1.], frameon=False, xticks=[],yticks=[])
ax.imshow(img, interpolation='none')

plt.savefig('D:\\mpl_logo.png', dpi=dpi, transparent=True)
```
Note that i manually defined the axes position so that spans the entire figure. In a similar way as above you could add some margin around the image to allow for labels or colorbars etc. This example adds a 20% margin above the image, which is then used for plotting a title:
```
fig = plt.figure(figsize=(xinch,yinch/.8))

ax = plt.axes([0., 0., 1., .8], frameon=False, xticks=[],yticks=[])
ax.imshow(img, interpolation='none')
ax.set_title('Matplotlib is fun!', size=16, weight='bold')

plt.savefig('D:\\mpl_logo_with_title.png', dpi=dpi)
```
So the figure y-size (height) is increased and the y-size of the axes is decreased equally. This gives a larger (overall) output image, but the axes area will still be the same size. It might be nice the have a figure or axes property like .set_scale() to force a true 1-on-x output.


Question: How to draw a line outside of an axis in matplotlib (in figure coordinates) Matplotlib has a function that writes text in figure coordinates (.figtext()) Is there a way to do the same but for drawing lines? In particular my goal is to draw lines to group some ticks on the y-axis together.

Response:
Tested in python 3.8.12, matplotlib 3.4.3
```py
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.lines import Line2D

x = np.linspace(0,10,100)
y = np.sin(x)*(1+x)

fig, ax = plt.subplots()
ax.plot(x,y,label='a')

# new clear axis overlay with 0-1 limits
ax2 = plt.axes([0,0,1,1], facecolor=(1,1,1,0))

x,y = np.array([[0.05, 0.1, 0.9], [0.05, 0.5, 0.9]])
line = Line2D(x, y, lw=5., color='r', alpha=0.4)
ax2.add_line(line)

plt.show()
```
But if you want to align with ticks, then why not use plot coordinates?


Question:
Scatter plot colorbar - Matplotlib I'm trying to show a color bar of my scatter plot but I'm keep getting the error: TypeError: You must first set_array for mappable This is what I'm doing to plot:
```
# Just plotting the values of data that are nonzero
x_data = numpy.nonzero(data)[0] # x coordinates
y_data = numpy.nonzero(data)[1] # y coordinates

# Mapping the values to RGBA colors
data = plt.cm.jet(data[x_data, y_data])

pts = plt.scatter(x_data, y_data, marker='s', color=data)

plt.colorbar(pts)
```
If I comment the line plt.colorbar(pts) I got the plot correctly, but I would like to plot the color bar too. Thank you in advance.

Response:
You're passing in specific rgb values, so matplotlib can't construct a colormap, because it doesn't know how it relates to your original data. Instead of mapping the values to RGB colors, let scatter handle that for you. Instead of:
```
# Mapping the values to RGBA colors
data = plt.cm.jet(data[x_data, y_data])

pts = plt.scatter(x_data, y_data, marker='s', color=data)
```
Do:
```
pts = plt.scatter(x_data, y_data, marker='s', c=data[x_data, y_data])
```
(Just pass in to c what you were originally passing into plt.cm.jet.) Then you'll be able to construct a colormap normally. The specific error is telling you that the colors have been manually set, rather than set through set_array (which handles mapping an array of data values to RGB).


Question:
Set minor tick label spacing on a log axis, and change colorbar tick label size I am trying to create a plot but I just want the ticklabels to show as shown where the log scale is shown as above. I only want the minor ticklabel for 50, 500 and 2000 to show. Is there anyway to specify the minor tick labels to show?? I have been trying to figure this out for a bit but haven't found a good solution. All I can think of is to get the minorticklabels() and set the fontsize to 0. This is shown below the first snippet of code. I was hoping there was a more clean solution. The other thing is changing the size of the ticklabels in the colorbar which I haven't figured out. If anyone knows of a way to do this please let me know because I don't see a method in colorbar that easily does this. First code:
```
fig = figure(figto)
ax = fig.add_subplot(111)
actShape = activationTrace.shape
semitones = arange(actShape[1])
freqArray = arange(actShape[0])
X,Y = meshgrid(self.testFreqArray,self.testFreqArray)
Z = sum(activationTrace[:,:,beg:end],axis=2)
surf = ax.contourf(X,Y,Z, 8, cmap=cm.jet)
ax.set_position([0.12,0.15,.8,.8])
ax.set_ylabel('Log Frequency (Hz)')
ax.set_xlabel('Log Frequency (Hz)')
ax.set_xscale('log')
ax.set_yscale('log')
ax.xaxis.set_minor_formatter(FormatStrFormatter('%d'))
ax.yaxis.set_ticks_position('left')
ax.xaxis.set_ticks_position('bottom')
ax.tick_params(axis='both',reset=False,which='both',length=8,width=2)
self.plotSetAxisLabels(ax,22)
self.plotSetAxisTickLabels(ax,18)
cbar = fig.colorbar(surf, shrink=0.5, aspect=20, fraction=.12,pad=.02)
cbar.set_label('Activation',size=18)
return ax, cbar
```
Second Code:
```
fig = figure(figto)
ax = fig.add_subplot(111)
actShape = activationTrace.shape
semitones = arange(actShape[1])
freqArray = arange(actShape[0])
X,Y = meshgrid(self.testFreqArray,self.testFreqArray)
Z = sum(activationTrace[:,:,beg:end],axis=2)
surf = ax.contourf(X,Y,Z, 8, cmap=cm.jet)
ax.set_position([0.12,0.15,.8,.8])
ax.set_ylabel('Log Frequency (Hz)')
ax.set_xlabel('Log Frequency (Hz)')
ax.set_xscale('log')
ax.set_yscale('log')
ax.xaxis.set_minor_formatter(FormatStrFormatter('%d'))
ax.yaxis.set_minor_formatter(FormatStrFormatter('%d'))
ax.yaxis.set_ticks_position('left')
ax.xaxis.set_ticks_position('bottom')
ax.tick_params(axis='both',reset=False,which='both',length=8,width=2)
self.plotSetAxisLabels(ax,22)
self.plotSetAxisTickLabels(ax,18)
cbar = fig.colorbar(surf, shrink=0.5, aspect=20, fraction=.12,pad=.02)
cbar.set_label('Activation',size=18)
count = 0
for i in ax.xaxis.get_minorticklabels():
    if (count%4 == 0):
        i.set_fontsize(12)
    else:
        i.set_fontsize(0)
    count+=1
for i in ax.yaxis.get_minorticklabels():
    if (count%4 == 0):
        i.set_fontsize(12)
    else:
        i.set_fontsize(0)
    count+=1
return ax, cbar
```
For the colorbar: Another quick question if you don't mind because trying to figure it out but not entirely sure. I want to use scientific notation which I can get with ScalarFormatter. How do I set the number of decimal places and the multiplier?? I'd like it to be like 8x10^8 or .8x10^9 to save space instead of putting all those zeros. I figure there is multiple ways to do this inside the axes object but what do you reckon is the best way. I can't figure out how to change the notation when changing to the ScalarFormatter. For the chart: Also, my data has points starting at 46 and then at successive multiplies of that multiplied by 2^(1/12) so 46,49,50,55,58,61...3132. These are all rounded but lie close to the 2^(1/12). I decided it better to place major tickers close to these numbers. Is the best way to use the fixed formatter and use a ticker every 15 or so in the freqArray. Then use a minor ticker at every other frequency. Can I do this and still maintain a log axis??

Response:
Use FixedLocator to statically define explicit tick locations. Colorbar cbar will have an .ax attribute that will provide access to the usual axis methods including tick formatting. This is not a reference to an axes (e.g. ax1, ax2, etc.).
```py
import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111)
x = np.arange(10,3000,100)
y = np.arange(10,3000,100)
X,Y = np.meshgrid(x,y)
Z = np.random.random(X.shape)*8000000
surf = ax.contourf(X,Y,Z, 8, cmap=plt.cm.jet)
ax.set_ylabel('Log Frequency (Hz)')
ax.set_xlabel('Log Frequency (Hz)')
ax.set_xscale('log')
ax.set_yscale('log')
ax.xaxis.set_minor_formatter(plt.FormatStrFormatter('%d'))
# defining custom minor tick locations:
ax.xaxis.set_minor_locator(plt.FixedLocator([50,500,2000]))
ax.yaxis.set_ticks_position('left')
ax.xaxis.set_ticks_position('bottom')
ax.tick_params(axis='both',reset=False,which='both',length=8,width=2)
cbar = fig.colorbar(surf, shrink=0.5, aspect=20, fraction=.12,pad=.02)
cbar.set_label('Activation',size=18)
# access to cbar tick labels:
cbar.ax.tick_params(labelsize=5)
plt.show()
```
Edit If you want the tick marls, but you want to selectively show the labels, I see nothing wrong with your iteration, except I might use set_visible instead of making the fontsize zero. You might enjoy finer control using a FuncFormatter where you can use the value or position of the tick to decide whether it gets shown:
```
def show_only_some(x, pos):
    s = str(int(x))
    if s[0] in ('2','5'):
        return s
    return ''

ax.xaxis.set_minor_formatter(plt.FuncFormatter(show_only_some))
```


Question: Plotting Pandas DataFrames in to Pie Charts using matplotlib Is it possible to print a DataFrame as a pie chart using matplotlib? The Pandas documentation on chart visualization has instructions for plotting lot of chart types including bar, histogram, scatter plot etc. But pie chart is missing?

Response:
To plot a pie chart from a dataframe df you can use Panda's plot.pie:
```
df.plot.pie(y='column_name')
```
Example:
```
import pandas as pd

df = pd.DataFrame({'activity': ['Work', 'Sleep', 'Play'],
                   'hours': [8, 10, 6]})
df.set_index('activity', inplace=True)
print(df)
#               hours
# activity
# Work          8
# Sleep        10
# Play          6
plot = df.plot.pie(y='hours', figsize=(7, 7))
```
Note that the labels of the pie chart are the index entries, this is the reason for using set_index to set the index to activity. To style the plot, you can use all those arguments that can be passed to DataFrame.plot(), here an example showing percentages:
```
plot = df.plot.pie(y='hours', title="Title", legend=False, \
                   autopct='%1.1f%%', explode=(0, 0, 0.1), \
                   shadow=True, startangle=0)
```