Question: Interactive matplotlib plot with two sliders I used matplotlib to create some plot, which depends on 8 variables. I would like to study how the plot changes when I change some of them. I created some script that calls the matplotlib one and generates different snapshots that later I convert into a movie, it is not bad, but a bit clumsy. I wonder if somehow I could interact with the plot regeneration using keyboard keys to increase / decrease values of some of the variables and see instantly how the plot changes. What is the best approach for this? Also if you can point me to interesting links or a link with a plot example with just two sliders?

Response:
In addition to what @triplepoint mentioned, have a look at the slider widget. There's an example on the matplotlib examples page. It's a graphical slider bar rather than keyboard bindings, but it works quite well for what you want to do. Also note that to guarantee the sliders and buttons remain responsive and not garbage-collected, references to the objects (amp_slider, freq_slider, etc.) should be maintained by yourself. (I'm making this community wiki, as I'm just copy-pasting from the example. This particular example teaches bad habits (e.g. from pylab import *), but it gets the point across. The example has been fixed to avoid the use of pylab.)
```
from numpy import pi, sin
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button, RadioButtons

def signal(amp, freq):
    return amp * sin(2 * pi * freq * t)

axis_color = 'lightgoldenrodyellow'

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

# Adjust the subplots region to leave some space for the sliders and buttons
fig.subplots_adjust(left=0.25, bottom=0.25)

t = np.arange(0.0, 1.0, 0.001)
amp_0 = 5
freq_0 = 3

# Draw the initial plot
# The 'line' variable is used for modifying the line later
[line] = ax.plot(t, signal(amp_0, freq_0), linewidth=2, color='red')
ax.set_xlim([0, 1])
ax.set_ylim([-10, 10])

# Add two sliders for tweaking the parameters

# Define an axes area and draw a slider in it
amp_slider_ax  = fig.add_axes([0.25, 0.15, 0.65, 0.03], facecolor=axis_color)
amp_slider = Slider(amp_slider_ax, 'Amp', 0.1, 10.0, valinit=amp_0)

# Draw another slider
freq_slider_ax = fig.add_axes([0.25, 0.1, 0.65, 0.03], facecolor=axis_color)
freq_slider = Slider(freq_slider_ax, 'Freq', 0.1, 30.0, valinit=freq_0)

# Define an action for modifying the line when any slider's value changes
def sliders_on_changed(val):
    line.set_ydata(signal(amp_slider.val, freq_slider.val))
    fig.canvas.draw_idle()
amp_slider.on_changed(sliders_on_changed)
freq_slider.on_changed(sliders_on_changed)

# Add a button for resetting the parameters
reset_button_ax = fig.add_axes([0.8, 0.025, 0.1, 0.04])
reset_button = Button(reset_button_ax, 'Reset', color=axis_color, hovercolor='0.975')
def reset_button_on_clicked(mouse_event):
    freq_slider.reset()
    amp_slider.reset()
reset_button.on_clicked(reset_button_on_clicked)

# Add a set of radio buttons for changing color
color_radios_ax = fig.add_axes([0.025, 0.5, 0.15, 0.15], facecolor=axis_color)
color_radios = RadioButtons(color_radios_ax, ('red', 'blue', 'green'), active=0)
def color_radios_on_clicked(label):
    line.set_color(label)
    fig.canvas.draw_idle()
color_radios.on_clicked(color_radios_on_clicked)

plt.show()
```


Question:
\text does not work in a matplotlib label I am using matplotlib together with latex labels for the axis, title and colorbar labels While it works really great most of the time, it has some issues when you have a formula using \text. One really simple example.
```
from matplotlib import pyplot as plt
plt.plot([1,2,3])
plt.title(r"$f_{\text{cor, r}}$")

plt.show()
```
This will result in an error message like:
```
IPython/core/formatters.py:239: FormatterWarning: Exception in image/png formatter:
f_{\text{1cor, r}}
   ^
Unknown symbol: \text (at char 3), (line:1, col:4)
  FormatterWarning,
```
Is there an easy way to use \text in there?

Response:
\text won't work because it requires the amsmath package (not included in mathtext - the math rendering engine of matplotlib). So you basically have two options: use latex based font rendering
```py
from matplotlib import pyplot as plt
import matplotlib as mpl
mpl.rcParams['text.usetex'] = True
mpl.rcParams['text.latex.preamble'] = [r'\usepackage{amsmath}'] #for \text command
plt.plot([1,2,3])
plt.title(r"$f_{\text{cor, r}}$")
plt.show()
```
use mathtext but use \mathrm instead of \text
```py
from matplotlib import pyplot as plt
import matplotlib as mpl
mpl.rcParams['text.usetex'] = False  # not really needed
plt.plot([1,2,3])
plt.title(r"$f_{\mathrm{cor, r}}$")
plt.show()
```
The latter approach creates a figure like Be aware that unlike with the \text command, spaces inside the \mathrm environment are not respected. If you want more space between the variables you have to use latex style commands (\, \;, ...).


Question:
show origin axis (x,y) in matplotlib plot I have following simple plot, and I would like to display the origin axis (x, y). I already have grid, but I need the x, y axis to be emphasized. this is my code:
```
x = linspace(0.2,10,100)
plot(x, 1/x)
plot(x, log(x))
axis('equal')
grid()
```
I have seen this question. The accepted answer suggests to use "Axis spine" and just links to some example. The example is however too complicated, using subplots. I am unable to figure out, how to use "Axis spine" in my simple example.

Response:
Using subplots is not too complicated, the spines might be. Dumb, simple way:
```
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0.2,10,100)
fig, ax = plt.subplots()
ax.plot(x, 1/x)
ax.plot(x, np.log(x))
ax.set_aspect('equal')
ax.grid(True, which='both')

ax.axhline(y=0, color='k')
ax.axvline(x=0, color='k')
```
And I get: (you can't see the vertical axis since the lower x-limit is zero.) Alternative using simple spines
```
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0.2,10,100)
fig, ax = plt.subplots()
ax.plot(x, 1/x)
ax.plot(x, np.log(x))
ax.set_aspect('equal')
ax.grid(True, which='both')

# set the x-spine (see below for more info on `set_position`)
ax.spines['left'].set_position('zero')

# turn off the right spine/ticks
ax.spines['right'].set_color('none')
ax.yaxis.tick_left()

# set the y-spine
ax.spines['bottom'].set_position('zero')

# turn off the top spine/ticks
ax.spines['top'].set_color('none')
ax.xaxis.tick_bottom()
```
Alternative using seaborn (my favorite)
```
import numpy as np
import matplotlib.pyplot as plt
import seaborn
seaborn.set(style='ticks')

x = np.linspace(0.2,10,100)
fig, ax = plt.subplots()
ax.plot(x, 1/x)
ax.plot(x, np.log(x))
ax.set_aspect('equal')
ax.grid(True, which='both')
seaborn.despine(ax=ax, offset=0) # the important part here
```
Using the set_position method of a spine Here are the docs for a the set_position method of spines: Spine position is specified by a 2 tuple of (position type, amount). The position types are: 'outward' : place the spine out from the data area by the specified number of points. (Negative values specify placing the spine inward.) 'axes' : place the spine at the specified Axes coordinate (from 0.0-1.0). 'data' : place the spine at the specified data coordinate. Additionally, shorthand notations define a special positions: 'center' -> ('axes',0.5) 'zero' -> ('data', 0.0) So you can place, say the left spine anywhere with: ax.spines['left'].set_position((system, poisition)) where system is 'outward', 'axes', or 'data' and position in the place in that coordinate system.


Question:
How to plot empirical CDF (ECDF) How can I plot the empirical CDF of an array of numbers with Matplotlib in Python? I'm looking for the CDF analog of Pylab’s hist function. One thing I can think of is:
```
from scipy.stats import cumfreq
a = array([...]) # my array of numbers
num_bins =  20
b = cumfreq(a, num_bins)
plt.plot(b)
```

Response:
If you like linspace and prefer one-liners, you can do:
```
plt.plot(np.sort(a), np.linspace(0, 1, len(a), endpoint=False))
```
Given my tastes, I almost always do:
```
# a is the data array
x = np.sort(a)
y = np.arange(len(x))/float(len(x))
plt.plot(x, y)
```
Which works for me even if there are >O(1e6) data values. If you really need to downsample I'd set
```
x = np.sort(a)[::down_sampling_step]
```
Edit to respond to comment/edit on why I use endpoint=False or the y as defined above. The following are some technical details. The empirical CDF is usually formally defined as
```
CDF(x) = "number of samples <= x"/"number of samples"
```
in order to exactly match this formal definition you would need to use y = np.arange(1,len(x)+1)/float(len(x)) so that we get y = [1/N, 2/N ... 1]. This estimator is an unbiased estimator that will converge to the true CDF in the limit of infinite samples Wikipedia ref.. I tend to use y = [0, 1/N, 2/N ... (N-1)/N] since: (a) it is easier to code/more idiomatic, (b) but is still formally justified since one can always exchange CDF(x) with 1-CDF(x) in the convergence proof, and (c) works with the (easy) downsampling method described above. In some particular cases, it is useful to define
```
y = (arange(len(x))+0.5)/len(x)
```
which is intermediate between these two conventions. Which, in effect, says "there is a 1/(2N) chance of a value less than the lowest one I've seen in my sample, and a 1/(2N) chance of a value greater than the largest one I've seen so far. Note that the selection of this convention interacts with the where parameter used in the plt.step if it seems more useful to display the CDF as a piecewise constant function. In order to exactly match the formal definition mentioned above, one would need to use where=pre the suggested y=[0,1/N..., 1-1/N] convention, or where=post with the y=[1/N, 2/N ... 1] convention, but not the other way around. However, for large samples, and reasonable distributions, the convention is given in the main body of the answer is easy to write, is an unbiased estimator of the true CDF, and works with the downsampling methodology.


Question:
Use a loop to plot n charts Python I have a set of data that I load into python using a pandas dataframe. What I would like to do is create a loop that will print a plot for all the elements in their own frame, not all on one. My data is in an excel file structured in this fashion:
```
Index | DATE  | AMB CO 1 | AMB CO 2 |...|AMB CO_n | TOTAL
1     | 1/1/12|  14      | 33       |...|  236    | 1600
.     | ...   | ...      | ...      |...|  ...    | ...
.     | ...   | ...      | ...      |...|  ...    | ...
.     | ...   | ...      | ...      |...|  ...    | ...
n
```
This is what I have for code so far:
```
import pandas as pd
import matplotlib.pyplot as plt
ambdf = pd.read_excel('Ambulance.xlsx',
                      sheetname='Sheet2', index_col=0, na_values=['NA'])
print type(ambdf)
print ambdf
print ambdf['EAS']

amb_plot = plt.plot(ambdf['EAS'], linewidth=2)
plt.title('EAS Ambulance Numbers')
plt.xlabel('Month')
plt.ylabel('Count of Deliveries')
print amb_plot

for i in ambdf:
    print plt.plot(ambdf[i], linewidth = 2)
```
I am thinking of doing something like this:
```
for i in ambdf:
    ambdf_plot = plt.plot(ambdf, linewidth = 2)
```
The above was not remotely what i wanted and it stems from my unfamiliarity with Pandas, MatplotLib etc, looking at some documentation though to me it looks like matplotlib is not even needed (question 2) So A) How can I produce a plot of data for every column in my df and B) do I need to use matplotlib or should I just use pandas to do it all? Thank you,

Response:
Ok, so the easiest method to create several plots is this:
```
import matplotlib.pyplot as plt
x=[[1,2,3,4],[1,2,3,4],[1,2,3,4],[1,2,3,4]]
y=[[1,2,3,4],[1,2,3,4],[1,2,3,4],[1,2,3,4]]
for i in range(len(x)):
    plt.figure()
    plt.plot(x[i],y[i])
    # Show/save figure as desired.
    plt.show()
# Can show all four figures at once by calling plt.show() here, outside the loop.
#plt.show()
```
Note that you need to create a figure every time or pyplot will plot in the first one created. If you want to create several data series all you need to do is:
```
import matplotlib.pyplot as plt
plt.figure()
x=[[1,2,3,4],[1,2,3,4],[1,2,3,4],[1,2,3,4]]
y=[[1,2,3,4],[2,3,4,5],[3,4,5,6],[7,8,9,10]]
plt.plot(x[0],y[0],'r',x[1],y[1],'g',x[2],y[2],'b',x[3],y[3],'k')
```
You could automate it by having a list of colours like ['r','g','b','k'] and then just calling both entries in this list and corresponding data to be plotted in a loop if you wanted to. If you just want to programmatically add data series to one plot something like this will do it (no new figure is created each time so everything is plotted in the same figure):
```
import matplotlib.pyplot as plt
x=[[1,2,3,4],[1,2,3,4],[1,2,3,4],[1,2,3,4]]
y=[[1,2,3,4],[2,3,4,5],[3,4,5,6],[7,8,9,10]]
colours=['r','g','b','k']
plt.figure() # In this example, all the plots will be in one figure.
for i in range(len(x)):
    plt.plot(x[i],y[i],colours[i])
plt.show()
```
If anything matplotlib has a very good documentation page with plenty of examples. 17 Dec 2019: added plt.show() and plt.figure() calls to clarify this part of the story.


Question:
How to move a tick label I would like to move some ticks' labels horizontally along the x-axis, without moving the corresponding ticks. More specifically, when rotating labels with plt.setp, the centers of the labels' text stay aligned with the ticks. I would like to shift those labels to the right, so that the near ends of the labels get aligned instead as suggested on the image below. I am aware of this post and this one, however the answers are interesting kludges rather than strict answers to the question. my code:
```
import matplotlib.pyplot as plt
import numpy as np
import datetime

# my fake data
dates = np.array([datetime.datetime(2000,1,1) + datetime.timedelta(days=i) for i in range(365*5)])
data = np.sin(np.arange(365*5)/365.0*2*np.pi - 0.25*np.pi) + np.random.rand(365*5) /3

# creates fig with 2 subplots
fig = plt.figure(figsize=(10.0, 6.0))
ax = plt.subplot2grid((2,1), (0, 0))
ax2 = plt.subplot2grid((2,1), (1, 0))
## plot dates
ax2.plot_date( dates, data )

# rotates labels
plt.setp( ax2.xaxis.get_majorticklabels(), rotation=-45 )

# try to shift labels to the right
ax2.xaxis.get_majorticklabels()[2].set_y(-.1)
ax2.xaxis.get_majorticklabels()[2].set_x(10**99)

plt.show()
```
Strangely enough, set_y behaves as expected, but even if I set x to a fantasillion, the labels would not move by one iota. (The use of plot_date may introduce additional confusion, but the same actually happens with plot.)

Response:
First of all, let's use a mcve to show the problem.
```
import numpy as np
import datetime
import matplotlib.pyplot as plt
plt.rcParams["date.autoformatter.month"] = "%b %Y"

# my fake data
dates = np.array([datetime.datetime(2000,1,1) + datetime.timedelta(days=i) for i in range(365)])
data = np.sin(np.arange(365)/365.0*2*np.pi - 0.25*np.pi) + np.random.rand(365) /3

# creates fig with 2 subplots
fig, ax = plt.subplots(figsize=(6,2))
## plot dates
ax.plot_date( dates, data )

# rotates labels
plt.setp( ax.xaxis.get_majorticklabels(), rotation=-45 )

plt.tight_layout()
plt.show()
```
Now as other anwers pointed out already, you may use horizontal alignment of the text.
```
# rotates labels and aligns them horizontally to left
plt.setp( ax.xaxis.get_majorticklabels(), rotation=-45, ha="left" )
```
You may use the rotation_mode argument to let the rotation happen about the top left point of the text, giving a slightly nicer result in this case.
```
# rotates labels and aligns them horizontally to left
plt.setp( ax.xaxis.get_majorticklabels(), rotation=-45, ha="left", rotation_mode="anchor")
```
In case those options are not fine grained enough, i.e. you want to position the labels more accurately, e.g. shifting it to the side by some points, you may use a transform. The following would offset the label by 5 points in horizontal direction, using a matplotlib.transforms.ScaledTranslation.
```
import matplotlib.transforms

plt.setp( ax.xaxis.get_majorticklabels(), rotation=-45)

# Create offset transform by 5 points in x direction
dx = 5/72.; dy = 0/72.
offset = matplotlib.transforms.ScaledTranslation(dx, dy, fig.dpi_scale_trans)

# apply offset transform to all x ticklabels.
for label in ax.xaxis.get_majorticklabels():
    label.set_transform(label.get_transform() + offset)
```
The advantage of this, compared to e.g. the solution provided by @explorerDude is that the offset is independent on the data in the graph, such that it is generally applicable to any plot and would look the same for a given fontsize.


Question:
How to show matplotlib plots? I am sure the configuration of matplotlib for python is correct since I have used it to plot some figures. But today it just stop working for some reason. I tested it with really simple code like:
```
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(0, 5, 0.1)
y = np.sin(x)
plt.plot(x, y)
```
There's no error but just no figure shown up. I am using python 2.6, Eclipse in Ubuntu

Response:
In matplotlib you have two main options: Create your plots and draw them at the end:
```
import matplotlib.pyplot as plt

plt.plot(x, y)
plt.plot(z, t)
plt.show()
```
Create your plots and draw them as soon as they are created:
```
import matplotlib.pyplot as plt
from matplotlib import interactive
interactive(True)

plt.plot(x, y)
raw_input('press return to continue')

plt.plot(z, t)
raw_input('press return to end')
```


Question:
How can I change the x axis so there is no white space? So currently learning how to import data and work with it in matplotlib and I am having trouble even tho I have the exact code from the book. This is what the plot looks like, but my question is how can I get it where there is no white space between the start and the end of the x-axis. Here is the code:
```
import csv

from matplotlib import pyplot as plt
from datetime import datetime

# Get dates and high temperatures from file.
filename = 'sitka_weather_07-2014.csv'
with open(filename) as f:
    reader = csv.reader(f)
    header_row = next(reader)

    #for index, column_header in enumerate(header_row):
        #print(index, column_header)
    dates, highs = [], []
    for row in reader:
        current_date = datetime.strptime(row[0], "%Y-%m-%d")
        dates.append(current_date)

        high = int(row[1])
        highs.append(high)

# Plot data.
fig = plt.figure(dpi=128, figsize=(10,6))
plt.plot(dates, highs, c='red')

# Format plot.
plt.title("Daily high temperatures, July 2014", fontsize=24)
plt.xlabel('', fontsize=16)
fig.autofmt_xdate()
plt.ylabel("Temperature (F)", fontsize=16)
plt.tick_params(axis='both', which='major', labelsize=16)

plt.show()
```

Response:
There is an automatic margin set at the edges, which ensures the data to be nicely fitting within the axis spines. In this case such a margin is probably desired on the y axis. By default it is set to 0.05 in units of axis span. To set the margin to 0 on the x axis, use
```
plt.margins(x=0)
```
or
```
ax.margins(x=0)
```
depending on the context. Also see the documentation. In case you want to get rid of the margin in the whole script, you can use
```
plt.rcParams['axes.xmargin'] = 0
```
at the beginning of your script (same for y of course). If you want to get rid of the margin entirely and forever, you might want to change the according line in the matplotlib rc file:
```
axes.xmargin : 0
axes.ymargin : 0
```
Example
```py
import seaborn as sns
import matplotlib.pyplot as plt

tips = sns.load_dataset('tips')

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4))
tips.plot(ax=ax1, title='Default Margin')
tips.plot(ax=ax2, title='Margins: x=0')
ax2.margins(x=0)
```
Alternatively, use plt.xlim(..) or ax.set_xlim(..) to manually set the limits of the axes such that there is no white space left.


Question:
How to hide  in IPython notebook [duplicate] This question already has answers here: Disable the output of matplotlib pyplot (4 answers) Closed 1 year ago. I am plotting a NumPy array of values, I, using IPython notebook in %matplotlib inline mode with the plot command plt.plot(I,'o'). The resulting output is:
```
<matplotlib.figure.Figure at 0x119e6ead0>
Out[159]:
[<matplotlib.lines.Line2D at 0x11ac57090>,
 <matplotlib.lines.Line2D at 0x11ac57310>,
 <matplotlib.lines.Line2D at 0x11ac57510>,
 <matplotlib.lines.Line2D at 0x11ac57690>,
 <matplotlib.lines.Line2D at 0x11ac57810>,
 <matplotlib.lines.Line2D at 0x11ac57990>,
 <matplotlib.lines.Line2D at 0x11ac57b10>,
 ....
 ....
]
```
Then my plot shows up below these lines of output. Is there a way to just show the plot and hide the  from the output?

Response:
You can use a semi-colon ; to end the line. This suppresses the unwanted output when generating plots:
```
plt.plot(I,'o');
```
In general, using a semi-colon stops IPython from printing any output value from that line of a code block. For example, the executing the cell containing the code 1+1; would not output 2. An alternative way would be to bind a variable to the plot:
```
_ = plt.plot(a)
```
This way, IPython only shows you the plots and the name _ is bound to the unwanted output.


Question:
How to shade region under the curve in matplotlib I want to use matplotlib to illustrate the definite integral between two regions: x_0, and x_1. How can I shade a region under a curve in matplotlib from x=-1, to x=1 given the following plot
```
import numpy as np
from matplotlib import pyplot as plt
def f(t):
    return t * t

t = np.arange(-4,4,1/40.)
plt.plot(t,f(t))
```

Response:
The final answer I came up with is to use fill_between. I thought there would have been a simple shade between type method, but this does exactly what I want.
```
section = np.arange(-1, 1, 1/20.)
plt.fill_between(section,f(section))
```


Question: How can I use seaborn without changing the matplotlib defaults? I am trying to use seaborn, because of its distplot function. But I prefer the default matplotlib settings. When I import seaborn, it changes automatically the appearance of my figure. How can I use seaborn functions without changing the look of the plots?

Response:
Version 0.8 (july 2017) changed this behaviour. From https://seaborn.pydata.org/whatsnew.html#v0-8-0-july-2017: The default (seaborn) style is no longer applied when seaborn is imported. It is now necessary to explicitly call set() or one or more of set_style(), set_context(), and set_palette(). Correspondingly, the seaborn.apionly module has been deprecated. For older versions, Import seaborn like this:
```
import seaborn.apionly as sns
```
and then you should be able to use sns.distplot but maintain the default matplotlib styling + your personal rc configuration.


Question:
Jupyter Notebook: interactive plot with widgets I am trying to generate an interactive plot that depends on widgets. The problem I have is that when I change parameters using the slider, a new plot is done after the previous one, instead I would expect only one plot changing according to the parameters. Example:
```
from ipywidgets import interact, interactive, fixed, interact_manual
import ipywidgets as widgets

import matplotlib.pyplot as plt
%matplotlib inline

import numpy as np

def plot_func(freq):
    x = np.linspace(0, 2*np.pi)
    y = np.sin(x * freq)
    plt.plot(x, y)

interact(plot_func, freq = widgets.FloatSlider(value=7.5,
                                               min=1,
                                               max=5.0,
                                               step=0.5))
```
After moving the slider to 4.0, I have: while I just want one figure to change as I move the slider. How can I achieve this? (I am using Python 2.7, matplotlib 2.0 and I have just updated notebook and jupyter to the latest version. let me know if further info is needed.)

Response:
As you want to change the figure, instead of creating a new one, may I suggest the following way: Use an interactive backend; %matplotlib notebook Update the line in the plot, instead of drawing new ones. So the code could look something like this:
```
%matplotlib notebook
from ipywidgets import *
import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 2 * np.pi)
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
line, = ax.plot(x, np.sin(x))

def update(w = 1.0):
    line.set_ydata(np.sin(w * x))
    fig.canvas.draw_idle()

interact(update);
```
Alternatively you may use plt.show() as in this answer.


Question:
Remove seaborn lineplot legend title I would like to remove the title from my seaborn lineplot legend. I tried using this answer to no avail:
```
import matplotlib.pyplot as plt
import seaborn as sns; sns.set()
fmri = sns.load_dataset("fmri")
fig, ax = plt.subplots()
g = sns.lineplot(x="timepoint", y="signal", hue="event", data=fmri, ax=ax)
ax.legend().set_title('')
```
I get the same if I try to set the title to None. Interestingly, setting the title to something else seems to prepend to the existing title:
```
ax.legend().set_title('Something else')
```
It almost looks like seaborn is treating the title as a hidden legend entry. How can I resolve this?

Response:
Important: This answer is about the case when a hue is used that appears as a legend title. In all other cases, the question itself already contains the usual way to get rid of a title. Indeed, seaborn is misusing a legend label as a (subgroup-)title. Hence the idea can be to either remove this label, or replace it with custom text. Replacing with custom text:
```
legend = ax.legend()
legend.texts[0].set_text("Whatever else")
```
Removing the label:
```
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles=handles[1:], labels=labels[1:])
```
After having removed the label you may of course still set another (real) title:
```
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles=handles[1:], labels=labels[1:], title="Whatever else")
```


Question:
How to change the plot line color from blue to black I am stuck when I have generated a set of data and tried to color the plot line in python. For example I would like to change the line color from blue to black here. This is what I have and returns is the set of data that I got from pandas.
```
ax=plt.gca()
ax.set_axis_bgcolor('#cccccc')
returns.plot()
```

Response:
The usual way to set the line color in matplotlib is to specify it in the plot command. This can either be done by a string after the data, e.g. "r-" for a red line, or by explicitely stating the color argument.
```
import matplotlib.pyplot as plt

plt.plot([1,2,3], [2,3,1], "r-") # red line
plt.plot([1,2,3], [5,5,3], color="blue") # blue line

plt.show()
```
See also the plot command's documentation. In case you already have a line with a certain color, you can change that with the lines2D.set_color() method.
```
line, = plt.plot([1,2,3], [4,5,3], color="blue")
line.set_color("black")
```
Setting the color of a line in a pandas plot is also best done at the point of creating the plot:
```
import matplotlib.pyplot as plt
import pandas as pd

df = pd.DataFrame({ "x" : [1,2,3,5], "y" : [3,5,2,6]})
df.plot("x", "y", color="r") #plot red line

plt.show()
```
If you want to change this color later on, you can do so by
```
plt.gca().get_lines()[0].set_color("black")
```
This will get you the first (possibly the only) line of the current active axes. In case you have more axes in the plot, you could loop through them
```
for ax in plt.gcf().axes:
    ax.get_lines()[0].set_color("black")
```
and if you have more lines you can loop over them as well.


Question: Resize a figure automatically in matplotlib Is there a way to automatically resize a figure to properly fit contained plots in a matplotlib/pylab image? I'm creating heatmap (sub)plots that differ in aspect ratio according to the data used. I realise I could calculate the aspect ratio and manually set it, but surely there's an easier way?

Response:
Use bbox_inches='tight'
```
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm

X = 10*np.random.rand(5,3)

fig = plt.figure(figsize=(15,5),facecolor='w')
ax = fig.add_subplot(111)
ax.imshow(X, cmap=cm.jet)

plt.savefig("image.png",bbox_inches='tight',dpi=100)
```
...only works when saving images though, not showing them.


Question:
Matplotlib: how to show legend elements horizontally? I'd like to set the legend to be displayed horizontally. I do not mean the text of the legend like described in the post Matplotlib legend vertical rotation. My actual case includes an arbitrary number of series specified with a widget. But the following example represents the gist of the challenge: Snippet:
```
# Imports
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

# data
np.random.seed(123)
x = pd.Series(np.random.randn(100),index=pd.date_range('1/1/2000', periods=100)).cumsum()
y = pd.Series(np.random.randn(100),index=pd.date_range('1/1/2000', periods=100)).cumsum()
z = pd.Series(np.random.randn(100),index=pd.date_range('1/1/2000', periods=100)).cumsum()
df = pd.concat([x,y,z], axis = 1)

# plot
ax = df.plot()
plt.legend(loc="lower left")
plt.show()
```
Plot: The default layout seems to be vertical. Looking at the details of help(ax.legend) and the docs , there does not seem to be a straight forward way to change this to horizontal. Or is there? Edit - Desired Legend: (using MS Paint)

Response:
Specify the ncol parameter in legend. In your case something like:
```
plt.legend(loc="lower left", ncol=len(df.columns))
```
This is the only line I changed in your script. Working full code:
```
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

# data
np.random.seed(123)
x = pd.Series(np.random.randn(100),index=pd.date_range('1/1/2000', periods=100)).cumsum()
y = pd.Series(np.random.randn(100),index=pd.date_range('1/1/2000', periods=100)).cumsum()
z = pd.Series(np.random.randn(100),index=pd.date_range('1/1/2000', periods=100)).cumsum()
df = pd.concat([x,y,z], axis = 1)

# plot
ax = plt.subplot()
for col in (df.columns):
    plt.plot(df[col])
plt.legend(loc="lower left", ncol=len(df.columns))
plt.xticks(rotation=90)
plt.show()
```


Question:
Reverse the order of a legend I use the following code to plot the bar graph and need to present a legend in reverse order. How can I do it?
```
colorsArr = plt.cm.BuPu(np.linspace(0, 0.5, len(C2)))
p = numpy.empty(len(C2), dtype=object)
plt.figure(figsize=(11, 11))

prevBar = 0
for index in range(len(C2)):
    plt.bar(ind, C2[index], width, bottom=prevBar, color=colorsArr[index],
            label=C0[index])
    prevBar = prevBar + C2[index]

# Positions of the x-axis ticks (center of the bars as bar labels)
tick_pos = [i + (width/2) for i in ind]

plt.ylabel('Home Category')
plt.title('Affinity - Retail Details(Home category)')

# Set the x ticks with names
plt.xticks(tick_pos, C1)
plt.yticks(np.arange(0, 70000, 3000))
plt.legend(title="Line", loc='upper left')

# Set a buffer around the edge
plt.xlim(-width*2, width*2)
plt.show()
```

Response:
You could call
```
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles[::-1], labels[::-1], title='Line', loc='upper left')
```
```
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(2016)

C0 = list('ABCDEF')
C2 = np.random.randint(20000, size=(len(C0), 3))
width = 1.0
C1 = ['foo', 'bar', 'baz']
ind = np.linspace(-width, width, len(C1))

colorsArr = plt.cm.BuPu(np.linspace(0, 0.5, len(C2)))
fig = plt.figure(figsize=(11,11))
ax = fig.add_subplot(1, 1, 1)

prevBar = 0
for height, color, label in zip(C2, colorsArr, C0):
    h = ax.bar(ind, height, width, bottom=prevBar, color=color, label=label)
    prevBar = prevBar + height

plt.ylabel('Home Category')
plt.title('Affinity - Retail Details(Home category)')

# positions of the x-axis ticks (center of the bars as bar labels)
tick_pos = [i+(width/2.0) for i in ind]
# set the x ticks with names
plt.xticks(tick_pos, C1)
plt.yticks(np.arange(0,70000,3000))

handles, labels = ax.get_legend_handles_labels()
ax.legend(handles[::-1], labels[::-1], title='Line', loc='upper left')

plt.show()
```


Question: Python Matplotlib Venn diagram I want to plot variables that belongs to certain groups. Say that I have 6 variables that I want to sort into these 3 groups and plot like a venn diagram. I would like to annotate the variable names into the three bubbles. In this simple example we could say that 1 variable is in group 1, 3 variables in group 2 and 2 variables in group 3. Could anyone help me with a simple example of how to do it in matplotlib?

Response:
There is a beautiful Venn diagram add-on for matplotlib called matplotlib-venn. It looks like it can be completely customized to do what you are looking for, from the size of the circles (proportional to the set size), to inner and outer labels. Using the example code on the website gives a plot like: Edit: Per the comments below the following code gives non-overlapping circles with text using the same library:
```
import pylab as plt
from matplotlib_venn import venn3, venn3_circles

v = venn3(subsets=(1,1,0,1,0,0,0))
v.get_label_by_id('100').set_text('First')
v.get_label_by_id('010').set_text('Second')
v.get_label_by_id('001').set_text('Third')
plt.title("Not a Venn diagram")
plt.show()
```
Gives the diagram:


Question:
Plotting a decision boundary separating 2 classes using Matplotlib's pyplot I could really use a tip to help me plotting a decision boundary to separate to classes of data. I created some sample data (from a Gaussian distribution) via Python NumPy. In this case, every data point is a 2D coordinate, i.e., a 1 column vector consisting of 2 rows. E.g.,
```
[ 1
  2 ]
```
Let's assume I have 2 classes, class1 and class2, and I created 100 data points for class1 and 100 data points for class2 via the code below (assigned to the variables x1_samples and x2_samples).
```
mu_vec1 = np.array([0,0])
cov_mat1 = np.array([[2,0],[0,2]])
x1_samples = np.random.multivariate_normal(mu_vec1, cov_mat1, 100)
mu_vec1 = mu_vec1.reshape(1,2).T # to 1-col vector

mu_vec2 = np.array([1,2])
cov_mat2 = np.array([[1,0],[0,1]])
x2_samples = np.random.multivariate_normal(mu_vec2, cov_mat2, 100)
mu_vec2 = mu_vec2.reshape(1,2).T
```
When I plot the data points for each class, it would look like this: Now, I came up with an equation for an decision boundary to separate both classes and would like to add it to the plot. However, I am not really sure how I can plot this function:
```
def decision_boundary(x_vec, mu_vec1, mu_vec2):
    g1 = (x_vec-mu_vec1).T.dot((x_vec-mu_vec1))
    g2 = 2*( (x_vec-mu_vec2).T.dot((x_vec-mu_vec2)) )
    return g1 - g2
```
I would really appreciate any help! EDIT: Intuitively (If I did my math right) I would expect the decision boundary to look somewhat like this red line when I plot the function...

Response:
Your question is more complicated than a simple plot : you need to draw the contour which will maximize the inter-class distance. Fortunately it's a well-studied field, particularly for SVM machine learning. The easiest method is to download the scikit-learn module, which provides a lot of cool methods to draw boundaries: scikit-learn: Support Vector Machines Code :
```
# -*- coding: utf-8 -*-

import numpy as np
import matplotlib
from matplotlib import pyplot as plt
import scipy
from sklearn import svm

mu_vec1 = np.array([0,0])
cov_mat1 = np.array([[2,0],[0,2]])
x1_samples = np.random.multivariate_normal(mu_vec1, cov_mat1, 100)
mu_vec1 = mu_vec1.reshape(1,2).T # to 1-col vector

mu_vec2 = np.array([1,2])
cov_mat2 = np.array([[1,0],[0,1]])
x2_samples = np.random.multivariate_normal(mu_vec2, cov_mat2, 100)
mu_vec2 = mu_vec2.reshape(1,2).T

fig = plt.figure()

plt.scatter(x1_samples[:,0],x1_samples[:,1], marker='+')
plt.scatter(x2_samples[:,0],x2_samples[:,1], c= 'green', marker='o')

X = np.concatenate((x1_samples,x2_samples), axis = 0)
Y = np.array([0]*100 + [1]*100)

C = 1.0  # SVM regularization parameter
clf = svm.SVC(kernel = 'linear',  gamma=0.7, C=C )
clf.fit(X, Y)
```
Linear Plot
```
w = clf.coef_[0]
a = -w[0] / w[1]
xx = np.linspace(-5, 5)
yy = a * xx - (clf.intercept_[0]) / w[1]

plt.plot(xx, yy, 'k-')
```
MultiLinear Plot
```
C = 1.0  # SVM regularization parameter
clf = svm.SVC(kernel = 'rbf',  gamma=0.7, C=C )
clf.fit(X, Y)

h = .02  # step size in the mesh
# create a mesh to plot in
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
                     np.arange(y_min, y_max, h))

# Plot the decision boundary. For that, we will assign a color to each
# point in the mesh [x_min, m_max]x[y_min, y_max].
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])

# Put the result into a color plot
Z = Z.reshape(xx.shape)
plt.contour(xx, yy, Z, cmap=plt.cm.Paired)
```
Implementation If you want to implement it yourself, you need to solve the following quadratic equation: The Wikipedia article Unfortunately, for non-linear boundaries like the one you draw, it's a difficult problem relying on a kernel trick but there isn't a clear cut solution.


Question: When to use imshow over pcolormesh I often find myself needing to create heatmap-style visualizations in Python with matplotlib. Matplotlib provides several functions which apparently do the same thing. pcolormesh is recommended instead of pcolor but what is the difference (from a practical point of view as a data plotter) between imshow and pcolormesh? What are the pros/cons of using one over the other? In what scenarios would one or the other be a clear winner?

Response: Fundamentally, imshow assumes that all data elements in your array are to be rendered at the same size, whereas pcolormesh/pcolor associates elements of the data array with rectangular elements whose size may vary over the rectangular grid. If your mesh elements are uniform, then imshow with interpolation set to "nearest" will look very similar to the default pcolormesh display (without the optional X and Y args). The obvious differences are that the imshow y-axis will be inverted (w.r.t. pcolormesh) and the aspect ratio is maintained, although those characteristics can be altered to look like the pcolormesh output as well. From a practical point of view, pcolormesh is more convenient if you want to visualize the data array as cells, particularly when the rectangular mesh is non-uniform or when you want to plot the boundaries/edges of the cells. Otherwise, imshow is more convenient if you have a fixed cell size, want to maintain aspect ratio, want control over pixel interpolation, or want to specify RGB values directly.


Question: How to add a grid line at a specific location in matplotlib plot? How do I add grid at a specific location on the y axis in a matplotlib plot?

Response:
Yes. It's very simple. Use the set_[x|y]ticks methods of axes object and toggle the grid as normal:
```
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.set_yticks([0.2, 0.6, 0.8], minor=False)
ax.set_yticks([0.3, 0.55, 0.7], minor=True)
ax.yaxis.grid(True, which='major')
ax.yaxis.grid(True, which='minor')
plt.show()
```


Question:
find length of sequences of identical values in a numpy array (run length encoding) In a pylab program (which could probably be a matlab program as well) I have a numpy array of numbers representing distances: d[t] is the distance at time t (and the timespan of my data is len(d) time units). The events I'm interested in are when the distance is below a certain threshold, and I want to compute the duration of these events. It's easy to get an array of booleans with b = d<threshold, and the problem comes down to computing the sequence of the lengths of the True-only words in b. But I do not know how to do that efficiently (i.e. using numpy primitives), and I resorted to walk the array and to do manual change detection (i.e. initialize counter when value goes from False to True, increase counter as long as value is True, and output the counter to the sequence when value goes back to False). But this is tremendously slow. How to efficienly detect that sort of sequences in numpy arrays ? Below is some python code that illustrates my problem : the fourth dot takes a very long time to appear (if not, increase the size of the array)
```
from pylab import *

threshold = 7

print '.'
d = 10*rand(10000000)

print '.'

b = d<threshold

print '.'

durations=[]
for i in xrange(len(b)):
    if b[i] and (i==0 or not b[i-1]):
        counter=1
    if  i>0 and b[i-1] and b[i]:
        counter+=1
    if (b[i-1] and not b[i]) or i==len(b)-1:
        durations.append(counter)

print '.'
```

Response:
Fully numpy vectorized and generic RLE for any array (works with strings, booleans etc too). Outputs tuple of run lengths, start positions, and values.
```
import numpy as np

def rle(inarray):
        """ run length encoding. Partial credit to R rle function.
            Multi datatype arrays catered for including non Numpy
            returns: tuple (runlengths, startpositions, values) """
        ia = np.asarray(inarray)                # force numpy
        n = len(ia)
        if n == 0:
            return (None, None, None)
        else:
            y = ia[1:] != ia[:-1]               # pairwise unequal (string safe)
            i = np.append(np.where(y), n - 1)   # must include last element posi
            z = np.diff(np.append(-1, i))       # run lengths
            p = np.cumsum(np.append(0, z))[:-1] # positions
            return(z, p, ia[i])
```
Pretty fast (i7):
```
xx = np.random.randint(0, 5, 1000000)
%timeit yy = rle(xx)
100 loops, best of 3: 18.6 ms per loop
```
Multiple data types:
```
rle([True, True, True, False, True, False, False])
Out[8]:
(array([3, 1, 1, 2]),
 array([0, 3, 4, 5]),
 array([ True, False,  True, False], dtype=bool))

rle(np.array([5, 4, 4, 4, 4, 0, 0]))
Out[9]: (array([1, 4, 2]), array([0, 1, 5]), array([5, 4, 0]))

rle(["hello", "hello", "my", "friend", "okay", "okay", "bye"])
Out[10]:
(array([2, 1, 1, 2, 1]),
 array([0, 2, 3, 4, 6]),
 array(['hello', 'my', 'friend', 'okay', 'bye'],
       dtype='|S6'))
```
Same results as Alex Martelli above:
```
xx = np.random.randint(0, 2, 20)

xx
Out[60]: array([1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1])

am = runs_of_ones_array(xx)

tb = rle(xx)

am
Out[63]: array([4, 5, 2, 5])

tb[0][tb[2] == 1]
Out[64]: array([4, 5, 2, 5])

%timeit runs_of_ones_array(xx)
10000 loops, best of 3: 28.5 µs per loop

%timeit rle(xx)
10000 loops, best of 3: 38.2 µs per loop
```
Slightly slower than Alex (but still very fast), and much more flexible.


Question:
seaborn color_palette as matplotlib colormap Seaborn offers a function called color_palette, which allows you to easily create new color_palettes for plots.
```
colors = ["#67E568","#257F27","#08420D","#FFF000","#FFB62B","#E56124","#E53E30","#7F2353","#F911FF","#9F8CA6"]

color_palette = sns.color_palette(colors)
```
I want to transform color_palette to a cmap, which I can use in matplotlib, but I don't see how I can do this. Sadly just functions like "cubehelix_palette","light_palette",… have an "as_cmap" paramater. "color_palette" doesn't, unfortunately.

Response:
You have to convert a list of colors from seaborn palette to color map of matplolib (thx to @RafaelLopes for proposed changes):
```
import seaborn as sns
import matplotlib.pylab as plt
import numpy as np
from matplotlib.colors import ListedColormap

# construct cmap
flatui = ["#9b59b6", "#3498db", "#95a5a6", "#e74c3c", "#34495e", "#2ecc71"]
my_cmap = ListedColormap(sns.color_palette(flatui).as_hex())

N = 500
data1 = np.random.randn(N)
data2 = np.random.randn(N)
colors = np.linspace(0,1,N)
plt.scatter(data1, data2, c=colors, cmap=my_cmap)
plt.colorbar()
plt.show()
```


Question:
Writing numerical values on the plot with Matplotlib Is it possible, with Matplotlib, to print the values of each point on the graph? For example, if I have:
```
x = numpy.range(0,10)
y = numpy.array([5,3,4,2,7,5,4,6,3,2])
pyplot.plot(x,y)
```
How can I display y values on the plot (e.g. print a 5 near the (0,5) point, print a 3 near the (1,3) point, etc.)?

Response:
You can use the annotate command to place text annotations at any x and y values you want. To place them exactly at the data points you could do this
```
import numpy
from matplotlib import pyplot

x = numpy.arange(10)
y = numpy.array([5,3,4,2,7,5,4,6,3,2])

fig = pyplot.figure()
ax = fig.add_subplot(111)
ax.set_ylim(0,10)
pyplot.plot(x,y)
for i,j in zip(x,y):
    ax.annotate(str(j),xy=(i,j))

pyplot.show()
```
If you want the annotations offset a little, you could change the annotate line to something like
```
ax.annotate(str(j),xy=(i,j+0.5))
```


Question:
How do I get a list of axes for a figure in pyplot? Regarding matplotlib.figure, the documentation says there is a class matplotlib.figure.AxesStack and that The AxesStack is a callable, where ax_stack() returns the current axes However, when I call fig.ax_stack(), I get the error:
```
AttributeError: 'Figure' object has no attribute 'ax_stack'
```

Response:
The property .axes returns a list of the Axes objects in the Figure object:
```
ax_list = fig.axes
```


Question:
How to change figuresize using seaborn factorplot
```
%pylab inline

import pandas as pd
import numpy as np
import matplotlib as mpl
import seaborn as sns

typessns = pd.DataFrame.from_csv('C:/data/testesns.csv', index_col=False, sep=';')

mpl.rc("figure", figsize=(45, 10))
sns.factorplot("MONTH", "VALUE", hue="REGION", data=typessns, kind="box", palette="OrRd");
```
I always get a small size figure, no matter what size I 've specified in figsize... How to fix it?

Response:
Note added in 2019: In modern seaborn versions the size argument has been renamed to height. To be a little more concrete:
```
%matplotlib inline

import seaborn as sns

exercise = sns.load_dataset("exercise")

# Defaults are size=5, aspect=1
sns.factorplot("kind", "pulse", "diet", exercise, kind="point", size=2, aspect=1)
sns.factorplot("kind", "pulse", "diet", exercise, kind="point", size=4, aspect=1)
sns.factorplot("kind", "pulse", "diet", exercise, kind="point", size=4, aspect=2)
```
You want to pass in the arguments 'size' or 'aspect' to the sns.factorplot() when constructing your plot. Size will change the height, while maintaining the aspect ratio (so it will also also get wider if only size is changed.) Aspect will change the width while keeping the height constant. The above code should be able to be run locally in an ipython notebook. Plot sizes are reduced in these examples to show the effects, and because the plots from the above code were fairly large when saved as png's. This also shows that size/aspect includes the legend in the margin. size=2, aspect=1 size=4, aspect=1 size=4, aspect=2 Also, all other useful parameters/arguments and defaults for this plotting function can be viewed with once the 'sns' module is loaded:
```
help(sns.factorplot)
```


Question: Row titles for matplotlib subplot In matplotlib, Is it possible to set a a separate title for each row of subplots in addition to the title set for the entire figure and the title set for each individual plot? This would correspond to the orange text in the figure below. If not, how would you get around this problem? Create a separate column of empty subplots to the left and fill them with the orange text? I am aware that it is possible to manually position each single title using text() or annotate(), but that usually requires a lot of tweaking and I have many subplots. Is there a smoother solution?

Response:
New in matplotlib 3.4.0 Row titles can now be implemented as subfigure suptitles: The new subfigure feature allows creating virtual figures within figures with localized artists (e.g., colorbars and suptitles) that only pertain to each subfigure. See how to plot subfigures for further details. How to reproduce OP's reference figure: Either Figure.subfigures (most straightforward) Create 3x1 fig.subfigures where each subfig gets its own 1x3 subfig.subplots and subfig.suptitle:
```py
fig = plt.figure(constrained_layout=True)
fig.suptitle('Figure title')

# create 3x1 subfigs
subfigs = fig.subfigures(nrows=3, ncols=1)
for row, subfig in enumerate(subfigs):
    subfig.suptitle(f'Subfigure title {row}')

    # create 1x3 subplots per subfig
    axs = subfig.subplots(nrows=1, ncols=3)
    for col, ax in enumerate(axs):
        ax.plot()
        ax.set_title(f'Plot title {col}')
```
Or Figure.add_subfigure (onto existing subplots) If you already have 3x1 plt.subplots, then add_subfigure into the underlying gridspec. Again each subfig will get its own 1x3 subfig.subplots and subfig.suptitle:
```py
# create 3x1 subplots
fig, axs = plt.subplots(nrows=3, ncols=1, constrained_layout=True)
fig.suptitle('Figure title')

# clear subplots
for ax in axs:
    ax.remove()

# add subfigure per subplot
gridspec = axs[0].get_subplotspec().get_gridspec()
subfigs = [fig.add_subfigure(gs) for gs in gridspec]

for row, subfig in enumerate(subfigs):
    subfig.suptitle(f'Subfigure title {row}')

    # create 1x3 subplots per subfig
    axs = subfig.subplots(nrows=1, ncols=3)
    for col, ax in enumerate(axs):
        ax.plot()
        ax.set_title(f'Plot title {col}')
```
Output of either example (after some styling):


Question:
How to plot the lines first and points last I have a simple plot with several sets of points and lines connecting each set. I want the points to be plotted on top of the lines (so that the line doesn't show inside the point). Regardless of order of the plot and scatter calls, this plot comes out the same, and not as I'd like. Is there a simple way to do it?
```
import math
import matplotlib.pyplot as plt

def poisson(m):
    def f(k):
        e = math.e**(-m)
        f = math.factorial(k)
        g = m**k
        return g*e/f
    return f

R = range(20)
L = list()
means = (1,4,10)
for m in means:
    f = poisson(m)
    L.append([f(k) for k in R])
colors = ['r','b','purple']

for c,P in zip(colors,L):
    plt.plot(R,P,color='0.2',lw=1.5)
    plt.scatter(R,P,s=150,color=c)

ax = plt.axes()
ax.set_xlim(-0.5,20)
ax.set_ylim(-0.01,0.4)
plt.savefig('example.png')
```

Response:
You need to set the Z-order.
```
plt.plot(R,P,color='0.2',lw=1.5, zorder=1)
plt.scatter(R,P,s=150,color=c, zorder=2)
```
Check out this example. http://matplotlib.sourceforge.net/examples/pylab_examples/zorder_demo.html


Question:
scatter plot logarithmic scale In my code, I take the logarithm of two data series and plot them. I would like to change each tick value of the x-axis by raising it to the power of e (anti-log of natural logarithm). In other words. I want to graph the logarithms of both series but have x-axis in levels. Here is the code that I'm using.
```
from pylab import scatter
import pylab
import matplotlib.pyplot as plt
import pandas as pd
from pandas import Series, DataFrame
import numpy as np

file_name = '/Users/joedanger/Desktop/Python/scatter_python.csv'

data = DataFrame(pd.read_csv(file_name))

y = np.log(data['o_value'], dtype='float64')
x = np.log(data['time_diff_day'], dtype='float64')

fig = plt.figure()
plt.scatter(x, y, c='blue', alpha=0.05, edgecolors='none')
fig.suptitle('test title', fontsize=20)
plt.xlabel('time_diff_day', fontsize=18)
plt.ylabel('o_value', fontsize=16)
plt.xticks([-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4])

plt.grid(True)
pylab.show()
```

Response:
let matplotlib take the log for you:
```
fig = plt.figure()
ax = plt.gca()
ax.scatter(data['o_value'] ,data['time_diff_day'] , c='blue', alpha=0.05, edgecolors='none')
ax.set_yscale('log')
ax.set_xscale('log')
```
If you are using all the same size and color markers, it is faster to use plot
```
fig = plt.figure()
ax = plt.gca()
ax.plot(data['o_value'] ,data['time_diff_day'], 'o', c='blue', alpha=0.05, markeredgecolor='none')
ax.set_yscale('log')
ax.set_xscale('log')
```


Question:
How to plot bar graphs with same X coordinates side by side ('dodged')
```
import matplotlib.pyplot as plt

gridnumber = range(1,4)

b1 = plt.bar(gridnumber, [0.2, 0.3, 0.1], width=0.4,
                label="Bar 1", align="center")

b2 = plt.bar(gridnumber, [0.3, 0.2, 0.2], color="red", width=0.4,
                label="Bar 2", align="center")

plt.ylim([0,0.5])
plt.xlim([0,4])
plt.xticks(gridnumber)
plt.legend()
plt.show()
```
Currently b1 and b2 overlap each other. How do I plot them separately like so:

Response:
Below answer will explain each and every line of code in the simplest manner possible:
```
# Numbers of pairs of bars you want
N = 3

# Data on X-axis

# Specify the values of blue bars (height)
blue_bar = (23, 25, 17)
# Specify the values of orange bars (height)
orange_bar = (19, 18, 14)

# Position of bars on x-axis
ind = np.arange(N)

# Figure size
plt.figure(figsize=(10,5))

# Width of a bar
width = 0.3

# Plotting
plt.bar(ind, blue_bar , width, label='Blue bar label')
plt.bar(ind + width, orange_bar, width, label='Orange bar label')

plt.xlabel('Here goes x-axis label')
plt.ylabel('Here goes y-axis label')
plt.title('Here goes title of the plot')

# xticks()
# First argument - A list of positions at which ticks should be placed
# Second argument -  A list of labels to place at the given locations
plt.xticks(ind + width / 2, ('Xtick1', 'Xtick3', 'Xtick3'))

# Finding the best position for legends and putting it
plt.legend(loc='best')
plt.show()
```


Question:
Logarithmic y-axis bins in python I'm trying to create a histogram of a data column and plot it logarithmically (y-axis) and I'm not sure why the following code does not work:
```
import numpy as np
import matplotlib.pyplot as plt
data = np.loadtxt('foo.bar')
fig = plt.figure()
ax = fig.add_subplot(111)
plt.hist(data, bins=(23.0, 23.5,24.0,24.5,25.0,25.5,26.0,26.5,27.0,27.5,28.0))
ax.set_xlim(23.5, 28)
ax.set_ylim(0, 30)
ax.grid(True)
plt.yscale('log')
plt.show()
```
I've also tried instead of plt.yscale('log') adding Log=true in the plt.hist line and also I tried ax.set_yscale('log'), but nothing seems to work. I either get an empty plot, either the y-axis is indeed logarithmic (with the code as shown above), but there is no data plotted (no bins).

Response:
try
```
plt.yscale('log', nonposy='clip')
```
http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.yscale The issue is with the bottom of bars being at y=0 and the default is to mask out in-valid points (log(0) -> undefined) when doing the log transformation (there was discussion of changing this, but I don't remember which way it went) so when it tries to draw the rectangles for you bar plot, the bottom edge is masked out -> no rectangles.


Question:
How do you directly overlay a scatter plot on top of a jpg image in matplotlib / Python? I need to rapidly plot jpg frames that result as the output of a tracking algorithm. Companion with the jpg frames are text files containing simple (x,y) data locating the image targets that are being tracked. I would like to use matplotlib to plot the jpg images, then overlay a scatter plot of the (x,y) data which gets read from the text file and stored into a Pythonic list. Below is code that will plot the jpg image, but in all of the scouring I have done of matplotlib, scipy, and PIL manuals and help pages, I cannot find anything that explains how to maintain this plot window and simply overlay a scatter plot of simple markers at various (x,y) locations in the image. Any help is greatly appreciated.
```
import matplotlib.pyplot as plt;
im = plt.imread(image_name);
implot = plt.imshow(im);
plt.show()
```

Response:
The pyplot.scatter() function was tailor made for this reason:
```
import matplotlib.pyplot as plt
im = plt.imread(image_name)
implot = plt.imshow(im)

# put a blue dot at (10, 20)
plt.scatter([10], [20])

# put a red dot, size 40, at 2 locations:
plt.scatter(x=[30, 40], y=[50, 60], c='r', s=40)

plt.show()
```
See the documentation for more info.


Question:
Is "from matplotlib import pyplot as plt" == "import matplotlib.pyplot as plt"?
```
from matplotlib import pyplot as plt

import matplotlib.pyplot as plt
```
Are the above statements equivalent? Which is more readable/better form?

Response: Even though they are equivalent, I think there is a pretty good argument that the second form import matplotlib.pyplot as plt is objectively more readable: It is generally customary to use import matplotlib.pyplot as plt and suggested in the matplotlib documentation (see http://matplotlib.org/users/pyplot_tutorial.html etc...) so this will be more familiar to most readers. import matplotlib.pyplot as plt is shorter but no less clear. import matplotlib.pyplot as plt gives an unfamiliar reader a hint that pyplot is a module, rather than a function which could be incorrectly assumed from the first form.


Question: Is it possible to have multiple PyPlot windows? Or am I limited to subplots? I'm not sure how to word my question more clearly. Basically, is PyPlot limited to one instance/window? Any hack or workaround I try either causes my program to freeze or for the second pyplot window to be queued until the first one is closed.

Response:
Sure, just open a new figure:
```
import matplotlib.pyplot as plt

plt.plot(range(10))

plt.figure()
plt.plot(range(10), 'ro-')

plt.figure(), plt.plot(...)

plt.show() # only do this once, at the end
```
If you're running this in the default python interpreter, this won't work, as each figure needs to enter the gui's mainloop. If you want to run things in an interactive shell, look into IPython. If you just run this normally (i.e. put it into a file and call python filename.py) it will work fine, though.


Question:
Figure to image as a numpy array I'm trying to get a numpy array image from a Matplotlib figure and I'm currently doing it by saving to a file, then reading the file back in, but I feel like there has to be a better way. Here's what I'm doing now:
```
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure

fig = Figure()
canvas = FigureCanvas(fig)
ax = fig.gca()

ax.text(0.0,0.0,"Test", fontsize=45)
ax.axis('off')

canvas.print_figure("output.png")
image = plt.imread("output.png")
```
I tried this:
```
image = np.fromstring( canvas.tostring_rgb(), dtype='uint8' )
```
from an example I found but it gives me an error saying that 'FigureCanvasAgg' object has no attribute 'renderer'.

Response:
In order to get the figure contents as RGB pixel values, the matplotlib.backend_bases.Renderer needs to first draw the contents of the canvas. You can do this by manually calling canvas.draw():
```
from matplotlib.figure import Figure

fig = Figure()
canvas = fig.canvas
ax = fig.gca()

ax.text(0.0,0.0,"Test", fontsize=45)
ax.axis('off')

canvas.draw()  # Draw the canvas, cache the renderer

image_flat = np.frombuffer(canvas.tostring_rgb(), dtype='uint8')  # (H * W * 3,)
# NOTE: reversed converts (W, H) from get_width_height to (H, W)
image = image_flat.reshape(*reversed(canvas.get_width_height()), 3)  # (H, W, 3)
```
See here for more info on the Matplotlib API.


Question:
percent label position in pie chart Is there a way to change the default position of the percent label in a matplotlib pie chart? Here is an example pie chart: Which I have created using:
```
plt.pie(sizes, labels=labels, colors=colors, explode=explode, autopct='%1.0f%%')
```
Now I don't like how some percent labels are intruding on other sections teritory (actually the only perpitrator in this example is the 9m section). Ideally I would like such labels to be outside the pie chart with an arrow of some sort pointing to the section, or alternativly just outside the section.

Response:
You can control the distance of the percents and labels from the center of the pie using pctdistance= and labeldistance=, try this on your code:
```
plt.pie(sizes, labels=labels, autopct='%1.0f%%', pctdistance=1.1, labeldistance=1.2)
```
You can also set a radius of the pie using radius= (by default is 1)


Question: How to change marker border width and hatch width? In this example of a marker from my scatter plot, I have set the color to green, and edge color to black, and hatch to "|". For the hatch pattern to show up at all, I must set the edgecolor; however when I do, I get a very thick border around the marker. Two questions: How can I to set the size of this border (preferably to 0)? How can I increase the thickness of the hatch lines?

Response:
You just need to set the linewidth to control the marker border thickness. You can increase the density of hatching, by repeating symbols (in the example below, the '|' is repeated in the R/H pane; note that to obtain NW->SE diagonal lines the symbol must be escaped so needs twice as many characters to really double it -- '\\\\' is density 2 while '||||' is density 4). However, I don't think the thickness of individual lines within hatching is controllable. See the code example below to produce scatter plots such as these:
```
import matplotlib.pyplot as plt
# generate some data
x = [1,2,3,4,5,8]
y= [i**2 for i in x]
y2= [60-i**2+3*i for i in x]

# plot markers with thick borders
plt.subplot(121)
plt.scatter(x,y, s=500, marker='s', edgecolor='black', linewidth=3, facecolor='green', hatch='|')
# compare with no borders, and denser hatch.
plt.subplot(122)
plt.scatter(x,y2, s=500, marker='s', edgecolor='black', linewidth=0, facecolor='green', hatch='||||')

plt.show()
```
matplotlib documentation on collections and scatter.


Question:
Creating a Colormap Legend in Matplotlib I am using imshow() in matplotlib like so:
```
import numpy as np
import matplotlib.pyplot as plt
mat = '''SOME MATRIX'''
plt.imshow(mat, origin="lower", cmap='gray', interpolation='nearest')
plt.show()
```
How do I add a legend showing the numeric value for the different shades of gray. Sadly, my googling has not uncovered an answer :( Thank you in advance for the help. Vince

Response:
Simple, just plt.colorbar():
```
import numpy as np
import matplotlib.pyplot as plt
mat = np.random.random((10,10))
plt.imshow(mat, origin="lower", cmap='gray', interpolation='nearest')
plt.colorbar()
plt.show()
```


Question:
Automatically Rescale ylim and xlim I'm plotting data in Python using matplotlib. I am updating the data of the plot based upon some calculations and want the ylim and xlim to be rescaled automatically. Instead what happens is the scale is set based upon the limits of the initial plot. A MWE is
```
import random
import matplotlib.pyplot as pyplot

pyplot.ion()

x = range(10)
y = lambda m: [m*random.random() for i in range(10)]

pLine, = pyplot.plot(x, y(1))

for i in range(10):
    pLine.set_ydata(y(i+1))
    pyplot.draw()
```
The first plot command generates a plot from [0,1] and I can see everything just fine. At the end, the y-data array goes from [0,10) with most of it greater than 1, but the y-limits of the figure remain [0,1]. I know I can manually change the limits using pyplot.ylim(...), but I don't know what to change them to. In the for loop, can I tell pyplot to scale the limits as if it was the first time being plotted?

Response:
You will need to update the axes' dataLim, then subsequently update the axes' viewLim based on the dataLim. The approrpiate methods are axes.relim() and ax.autoscale_view() method. Your example then looks like:
```
import random
import matplotlib.pyplot as pyplot

pyplot.ion()

x = range(10)
y = lambda m: [m*random.random() for i in range(10)]

pLine, = pyplot.plot(x, y(1))

for i in range(10):
    pLine.set_ydata(y(i+1))

ax = pyplot.gca()

# recompute the ax.dataLim
ax.relim()
# update ax.viewLim using the new dataLim
ax.autoscale_view()
pyplot.draw()
```


Question:
Remove the extra plot in the matplotlib subplot I want to plot 5 data frames in a 2 by 3 setting (i.e. 2 rows and 3 columns). This is my code: However there is an extra empty plot in the 6th position (second row and third column) which I want to get rid of it. I am wondering how I could remove it so that I have three plots in the first row and two plots in the second row.
```
import matplotlib.pyplot as plt
fig, axes = plt.subplots(nrows=2, ncols=3)

fig.set_figheight(8)
fig.set_figwidth(15)

df[2].plot(kind='bar',ax=axes[0,0]); axes[0,0].set_title('2')

df[4].plot(kind='bar',ax=axes[0,1]); axes[0,1].set_title('4')

df[6].plot(kind='bar',ax=axes[0,2]); axes[0,2].set_title('6')

df[8].plot(kind='bar',ax=axes[1,0]); axes[1,0].set_title('8')

df[10].plot(kind='bar',ax=axes[1,1]); axes[1,1].set_title('10')

plt.setp(axes, xticks=np.arange(len(observations)), xticklabels=map(str,observations),
        yticks=[0,1])

fig.tight_layout()
```

Response:
Try this:
```
fig.delaxes(axes[1][2])
```
A much more flexible way to create subplots is the fig.add_axes() method. The parameters is a list of rect coordinates: fig.add_axes([x, y, xsize, ysize]). The values are relative to the canvas size, so an xsize of 0.5 means the subplot has half the width of the window.


Question:
Get the list of figures in matplotlib I would like to:
```
pylab.figure()
pylab.plot(x)
pylab.figure()
pylab.plot(y)
# ...
for i, figure in enumerate(pylab.MagicFunctionReturnsListOfAllFigures()):
  figure.savefig('figure%d.png' % i)
```
What is the magic function that returns a list of current figures in pylab? Websearch didn't help...

Response:
Pyplot has get_fignums method that returns a list of figure numbers. This should do what you want:
```
import matplotlib.pyplot as plt
import numpy as np

x = np.arange(100)
y = -x

plt.figure()
plt.plot(x)
plt.figure()
plt.plot(y)

for i in plt.get_fignums():
    plt.figure(i)
    plt.savefig('figure%d.png' % i)
```


Question:
How to change the legend edgecolor and facecolor Is there while rcParams['legend.frameon'] = 'False' a simple way to fill the legend area background with a given colour. More specifically I would like the grid not to be seen on the legend area because it disturbs the text reading. The keyword framealpha sounds like what I need but it doesn't change anything.
```
import matplotlib as mpl
import matplotlib.pyplot as plt
mpl.rcParams['legend.frameon'] = 'False'
plt.plot(range(5), label = u"line")
plt.grid(True)
plt.legend(loc = best)
plt.show()
```
I've also tried:
```
legend = plt.legend(frameon = 1)
frame = legend.get_frame()
frame.set_color('white')
```
but then I need to ask how can I change the background colour while keeping the frame on? Sometimes I want it ON with a background colour other than white. And also, is there a way of changing the colour of the frame? With the above code I was expecting to change the colour of the frame only, not the background.

Response:
You can set the edge color and the face color separately like this:
```
frame.set_facecolor('green')
frame.set_edgecolor('red')
```
There's more information under FancyBboxPatch here.


Question:
Annotate data points while plotting from Pandas DataFrame I would like to annotate the data points with their values next to the points on the plot. The examples I found only deal with x and y as vectors. However, I would like to do this for a pandas DataFrame that contains multiple columns.
```
ax = plt.figure().add_subplot(1, 1, 1)
df.plot(ax = ax)
plt.show()
```
What is the best way to annotate all the points for a multi-column DataFrame?

Response:
Here's a (very) slightly slicker version of Dan Allan's answer:
```
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import string

df = pd.DataFrame({'x':np.random.rand(10), 'y':np.random.rand(10)},
                  index=list(string.ascii_lowercase[:10]))
```
Which gives:
```
x         y
a  0.541974  0.042185
b  0.036188  0.775425
c  0.950099  0.888305
d  0.739367  0.638368
e  0.739910  0.596037
f  0.974529  0.111819
g  0.640637  0.161805
h  0.554600  0.172221
i  0.718941  0.192932
j  0.447242  0.172469
```
And then:
```
fig, ax = plt.subplots()
df.plot('x', 'y', kind='scatter', ax=ax)

for k, v in df.iterrows():
    ax.annotate(k, v)
```
Finally, if you're in interactive mode you might need to refresh the plot:
```
fig.canvas.draw()
```
Which produces: Or, since that looks incredibly ugly, you can beautify things a bit pretty easily:
```
from matplotlib import cm
cmap = cm.get_cmap('Spectral')
df.plot('x', 'y', kind='scatter', ax=ax, s=120, linewidth=0,
        c=range(len(df)), colormap=cmap)

for k, v in df.iterrows():
    ax.annotate(k, v,
                xytext=(10,-5), textcoords='offset points',
                family='sans-serif', fontsize=18, color='darkslategrey')
```
Which looks a lot nicer:


Question:
Python ASCII plots in terminal With Octave I am able to plot arrays to the terminal, for example, plotting an array with values for the function x^2 gives this output in my terminal:
```
10000 ++---------+-----------+----------+-----------+---------++
         ++         +           +          +           +         ++
         |+         :           :          :           :         +|
         |++        :           :          :           :        ++|
         | +        :           :          :           :        + |
         | ++       :           :          :           :       ++ |
    8000 ++.+..................................................+.++
         |  ++      :           :          :           :      ++  |
         |   ++     :           :          :           :     ++   |
         |    +     :           :          :           :     +    |
         |    ++    :           :          :           :    ++    |
         |     +    :           :          :           :    +     |
    6000 ++....++..........................................++....++
         |      ++  :           :          :           :  ++      |
         |       +  :           :          :           :  +       |
         |       ++ :           :          :           : ++       |
         |        ++:           :          :           :++        |
    4000 ++........++..................................++........++
         |          +           :          :           +          |
         |          ++          :          :          ++          |
         |          :++         :          :         ++:          |
         |          : ++        :          :        ++ :          |
         |          :  ++       :          :       ++  :          |
    2000 ++.............++........................++.............++
         |          :    ++     :          :     ++    :          |
         |          :     +++   :          :   +++     :          |
         |          :       ++  :          :  ++       :          |
         |          :        +++:          :+++        :          |
         +          +          ++++      ++++          +          +
       0 ++---------+-----------+----------+-----------+---------++
         0        20000       40000      60000       80000     100000
```
Is there some way I can do something similar in Python, specifically with matplotlib? bashplotlib seems to offer some of this functionality but appears to be quite basic compared to Octave's offering.

Response:
As few answers already suggested the gnuplot is a great choice. However, there is no need to call a gnuplot subprocess, it might be much easier to use a python gnuplotlib library. Example (from: https://github.com/dkogan/gnuplotlib):
```

```python
import numpy as np
```

```python
import gnuplotlib as gp
```

```python
x = np.linspace(-5,5,100)
```

```python
gp.plot( x, np.sin(x) )
#Output
#[ graphical plot pops up showing a simple sinusoid ]
```

```python
gp.plot( (x, np.sin(x), {'with': 'boxes'}),
         (x, np.cos(x), {'legend': 'cosine'}),
         _with    = 'lines',
         terminal = 'dumb 80,40',
         unset    = 'grid')
```

[ ascii plot printed on STDOUT]
   1 +-+---------+----------+-----------+-----------+----------+---------+-+
     +     +|||+ +          +         +++++   +++|||+          +           +
     |     |||||+                    +     +  +||||||       cosine +-----+ |
 0.8 +-+   ||||||                    +     + ++||||||+                   +-+
     |     ||||||+                  +       ++||||||||+                    |
     |     |||||||                  +       ++|||||||||                    |
     |     |||||||+                +        |||||||||||                    |
 0.6 +-+   ||||||||               +         +||||||||||+                 +-+
     |     ||||||||+              |        ++|||||||||||                   |
     |     |||||||||              +        |||||||||||||                   |
 0.4 +-+   |||||||||              |       ++||||||||||||+                +-+
     |     |||||||||             +        +||||||||||||||                  |
     |     |||||||||+            +        |||||||||||||||                  |
     |     ||||||||||+           |       ++||||||||||||||+           +     |
 0.2 +-+   |||||||||||          +        |||||||||||||||||           +   +-+
     |     |||||||||||          |        +||||||||||||||||+          |     |
     |     |||||||||||         +         ||||||||||||||||||         +      |
   0 +-+   +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++   +-+
     |       +        ||||||||||||||||||+         |       ++||||||||||     |
     |       |        +|||||||||||||||||          +        |||||||||||     |
     |       +        ++||||||||||||||||          |        +||||||||||     |
-0.2 +-+      +        |||||||||||||||||          +        |||||||||||   +-+
     |        |        ++||||||||||||||+           |       ++|||||||||     |
     |        +         |||||||||||||||            +        ++||||||||     |
     |         |        +||||||||||||||            +         |||||||||     |
-0.4 +-+       +        ++||||||||||||+             |        +||||||||   +-+
     |          +        |||||||||||||              +        |||||||||     |
     |          |        +|||||||||||+               +       ++|||||||     |
-0.6 +-+        +        ++||||||||||                |        +|||||||   +-+
     |           +        |||||||||||                +        ++||||||     |
     |           +        +|||||||||+                 +        |||||||     |
     |            +       ++||||||||                  +       +++|||||     |
-0.8 +-+          +      + ++||||||+                   +      + +|||||   +-+
     |             +    +   +||||||                     +    +  ++||||     |
     +           +  +  ++   ++|||++     +           +   ++  +  + ++|||     +
  -1 +-+---------+----------+-----------+-----------+----------+---------+-+
    -6          -4         -2           0           2          4           6
```


Question: Plot multiple columns of pandas DataFrame using Seaborn suppose I have DataFrame with columns ['X_Axis','col_2','col_3',...,'col_n',] I need to plot the first column on X-Axis and rest on Y-Axis. FYI : all the values have been grouped according to X-Axis, the X-Axis values range from 0-25 and all other column values have been normalized to the scale of 0 - 1. I want it on same graph plot, not subplots. Preferred : FactorPlot , normal line graph.

Response:
Some seaborn plots will accept a wide dataframe, sns.pointplot(data=df, x='X_Axis', y='col_2'), but not sns.pointplot(data=df, x='X_Axis', y=['col_2', 'col_3']), so it's better to reshape the DataFrame. Reshape the DataFrame from wide to long with pandas.DataFrame.melt. Converting the dataframe from a wide to long form is standard for all seaborn plots, not just the examples shown. Tested in python 3.8.12, pandas 1.3.4, matplotlib 3.4.3, seaborn 0.11.2 Sample DataFrame
```py
import pandas as pd
import seaborn as sns

df = pd.DataFrame({'X_Axis':[1,3,5,7,10,20],
                   'col_2':[.4,.5,.4,.5,.5,.4],
                   'col_3':[.7,.8,.9,.4,.2,.3],
                   'col_4':[.1,.3,.5,.7,.1,.0],
                   'col_5':[.5,.3,.6,.9,.2,.4]})

# display(df)
   X_Axis  col_2  col_3  col_4  col_5
0       1    0.4    0.7    0.1    0.5
1       3    0.5    0.8    0.3    0.3
2       5    0.4    0.9    0.5    0.6
3       7    0.5    0.4    0.7    0.9
4      10    0.5    0.2    0.1    0.2
5      20    0.4    0.3    0.0    0.4

# convert to long (tidy) form
dfm = df.melt('X_Axis', var_name='cols', value_name='vals')

# display(dfm.head())
   X_Axis   cols  vals
0       1  col_2   0.4
1       3  col_2   0.5
2       5  col_2   0.4
3       7  col_2   0.5
4      10  col_2   0.5
```
Current Plot Methods catplot: figure-level Use seaborn.catplot with kind= (e.g. kind='point' to reproduce the FactorPlot default):
```py
g = sns.catplot(x="X_Axis", y="vals", hue='cols', data=dfm, kind='point')
```
pointplot: axes-level
```py
sns.pointplot(x="X_Axis", y="vals", hue='cols', data=dfm)
```
Original factorplot: was renamed to catplot v0.9.0 (July 2018) New versions of seaborn get warning: The factorplot function has been renamed to catplot. The original name will be removed in a future release. Please update your code. Note that the default kind in factorplot ('point') has changed 'strip' in catplot.
```py
g = sns.factorplot(x="X_Axis", y="vals", hue='cols', data=dfm)

# using pd.melt instead of pd.DataFrame.melt for pandas < 0.20.0
# dfm = pd.melt(df, 'X_Axis', var_name='cols',  value_name='vals')
# g = sns.factorplot(x="X_Axis", y="vals", hue='cols', data=dfm)
```


Question: How to smooth matplotlib contour plot? I have numpy array with this shape: (33,10). When I plot contour I get ugly image like this: while contour() doesn't seem to have any argument about smoothing or some sort of interpolation feature. I somehow expected that tool which offers contour plot should offer smoothing too. Is there straight forward way to do it in MPL?

Response:
As others have already pointed out, you need to interpolate your data. There are a number of different ways to do this, but for starters, consider scipy.ndimage.zoom. As a quick exmaple:
```
import numpy as np
import scipy.ndimage
import matplotlib.pyplot as plt

data = np.loadtxt('data.txt')

# Resample your data grid by a factor of 3 using cubic spline interpolation.
data = scipy.ndimage.zoom(data, 3)

plt.contour(data)
plt.show()
```


Question: How does one insert statistical annotations (stars or p-values) This seems like a trivial question, but I've been searching for a while and can't seem to find an answer. It also seems like something that should be a standard part of these packages. Does anyone know if there is a standard way to include statistical annotation between distribution plots in seaborn? For example, between two box or swarmplots?

Response:
A brace / bracket can be plotted direct with matplotlib.pyplot.plot or matplotlib.axes.Axes.plot, and annotations can be added with matplotlib.pyplot.text or matplotlib.axes.Axes.text. seaborn categorical plots are 0 indexed, whereas box plots, by default, with matplotlib and pandas, start at range(1, N+1), which can be adjusted with the positions parameter. seaborn is a high-level API for matplotlib, and pandas.DataFrame.plot uses matplotlib as the default backend. Imports and DataFrame
```py
import seaborn as sns
import matplotlib.pyplot as plt

# dataframe in long form for seaborn
tips = sns.load_dataset("tips")

# dataframe in wide form for plotting with pandas.DataFrame.plot
df = tips.pivot(columns='day', values='total_bill')

# data as a list of lists for plotting directly with matplotlib (no nan values allowed)
data = [df[c].dropna().tolist() for c in df.columns]
```
seaborn
```py
sns.boxplot(x="day", y="total_bill", data=tips, palette="PRGn")

# statistical annotation
x1, x2 = 2, 3   # columns 'Sat' and 'Sun' (first column: 0, see plt.xticks())
y, h, col = tips['total_bill'].max() + 2, 2, 'k'

plt.plot([x1, x1, x2, x2], [y, y+h, y+h, y], lw=1.5, c=col)
plt.text((x1+x2)*.5, y+h, "ns", ha='center', va='bottom', color=col)

plt.show()
```
pandas.DataFrame.plot
```py
ax = df.plot(kind='box', positions=range(len(df.columns)))

x1, x2 = 2, 3
y, h, col = df.max().max() + 2, 2, 'k'

ax.plot([x1, x1, x2, x2], [y, y+h, y+h, y], lw=1.5, c=col)
ax.text((x1+x2)*.5, y+h, "ns", ha='center', va='bottom', color=col)
```
matplotlib
```py
plt.boxplot(data, positions=range(len(data)))

x1, x2 = 2, 3

y, h, col = max(map(max, data)) + 2, 2, 'k'

plt.plot([x1, x1, x2, x2], [y, y+h, y+h, y], lw=1.5, c=col)
plt.text((x1+x2)*.5, y+h, "ns", ha='center', va='bottom', color=col)
```
tips.head()
```none
total_bill   tip     sex smoker  day    time  size
0       16.99  1.01  Female     No  Sun  Dinner     2
1       10.34  1.66    Male     No  Sun  Dinner     3
2       21.01  3.50    Male     No  Sun  Dinner     3
3       23.68  3.31    Male     No  Sun  Dinner     2
4       24.59  3.61  Female     No  Sun  Dinner     4
```
df.head()
```none
day  Thur  Fri  Sat    Sun
0     NaN  NaN  NaN  16.99
1     NaN  NaN  NaN  10.34
2     NaN  NaN  NaN  21.01
3     NaN  NaN  NaN  23.68
4     NaN  NaN  NaN  24.59
```
data
```none
[[27.2, 22.76, 17.29, ..., 20.53, 16.47, 18.78],
 [28.97, 22.49, 5.75, ..., 13.42, 16.27, 10.09],
 [20.65, 17.92, 20.29, ..., 29.03, 27.18, 22.67, 17.82],
 [16.99, 10.34, 21.01, ..., 18.15, 23.1, 15.69]]
```


Question:
How to remove or hide x-axis labels from a plot I have a boxplot and need to remove the x-axis ('user_type' and 'member_gender') label. How do I do this given the below format?
```
sb.boxplot(x="user_type", y="Seconds", data=df, color = default_color, ax = ax[0,0], sym='').set_title('User-Type (0=Non-Subscriber, 1=Subscriber)')
sb.boxplot(x="member_gender", y="Seconds", data=df, color = default_color, ax = ax[1,0], sym='').set_title('Gender (0=Male, 1=Female, 2=Other)')
```

Response:
After creating the boxplot, use .set(). .set(xticklabels=[]) should remove tick labels. This doesn't work if you use .set_title(), but you can use .set(title=''). Do not use sns.boxplot(...).set(xticklabels=[]) because, while this works, the object type is changed from matplotlib.axes._axes.Axes for sns.boxplot(...), to list. .set(xlabel=None) should remove the axis label. .tick_params(bottom=False) will remove the ticks. Similarly, for the y-axis: How to remove or hide y-axis ticklabels from a plot Tested in python 3.11, pandas 1.5.2, matplotlib 3.6.2, seaborn 0.12.1 From the OP: No sample data
```py
fig, ax = plt.subplots(2, 1)

g1 = sb.boxplot(x="user_type", y="Seconds", data=df, color = default_color, ax = ax[0], sym='')
g1.set(xticklabels=[])
g1.set(title='User-Type (0=Non-Subscriber, 1=Subscriber)')
g1.set(xlabel=None)

g2 = sb.boxplot(x="member_gender", y="Seconds", data=df, color = default_color, ax = ax[1], sym='')
g2.set(xticklabels=[])
g2.set(title='Gender (0=Male, 1=Female, 2=Other)')
g2.set(xlabel=None)
```
Example 1 With xticks and xlabel
```py
import seaborn as sns
import matplotlib.pyplot as plt

# load data
exercise = sns.load_dataset('exercise')
pen = sns.load_dataset('penguins')

# create figures
fig, ax = plt.subplots(2, 1, figsize=(8, 8))

# plot data
g1 = sns.boxplot(x='time', y='pulse', hue='kind', data=exercise, ax=ax[0])

g2 = sns.boxplot(x='species', y='body_mass_g', hue='sex', data=pen, ax=ax[1])

plt.show()
```
Without xticks and xlabel
```py
fig, ax = plt.subplots(2, 1, figsize=(8, 8))

g1 = sns.boxplot(x='time', y='pulse', hue='kind', data=exercise, ax=ax[0])

g1.set(xticklabels=[])  # remove the tick labels
g1.set(title='Exercise: Pulse by Time for Exercise Type')  # add a title
g1.set(xlabel=None)  # remove the axis label

g2 = sns.boxplot(x='species', y='body_mass_g', hue='sex', data=pen, ax=ax[1])

g2.set(xticklabels=[])
g2.set(title='Penguins: Body Mass by Species for Gender')
g2.set(xlabel=None)
g2.tick_params(bottom=False)  # remove the ticks

plt.show()
```
Example 2
```py
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

# sinusoidal sample data
sample_length = range(1, 1+1) # number of columns of frequencies
rads = np.arange(0, 2*np.pi, 0.01)
data = np.array([(np.cos(t*rads)*10**67) + 3*10**67 for t in sample_length])
df = pd.DataFrame(data.T, index=pd.Series(rads.tolist(), name='radians'), columns=[f'freq: {i}x' for i in sample_length])
df.reset_index(inplace=True)

# plot
fig, ax = plt.subplots(figsize=(8, 8))
ax.plot('radians', 'freq: 1x', data=df)

# or skip the previous two lines and plot df directly
# ax = df.plot(x='radians', y='freq: 1x', figsize=(8, 8), legend=False)
```
Remove Labels
```py
# plot
fig, ax = plt.subplots(figsize=(8, 8))
ax.plot('radians', 'freq: 1x', data=df)

# or skip the previous two lines and plot df directly
# ax = df.plot(x='radians', y='freq: 1x', figsize=(8, 8), legend=False)

ax.set(xticklabels=[])  # remove the tick labels
ax.tick_params(bottom=False)  # remove the ticks
```


Question:
No handles with labels found to put in legend I'm trying to create a parallelogram in PyPlot. I'm not up to drawing the parallelogram--first I'm putting in the vector arrows--using the following code:
```
fig = plt.figure()
ax = fig.add_subplot(111)
ax.spines['left'].set_position('zero')
ax.spines['right'].set_color('none')
ax.spines['bottom'].set_position('zero')
ax.spines['top'].set_color('none')
plt.axis([-5,5,-5,5])
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')
plt.grid()
plt.arrow(0,0, 3,1, head_width=0.2, color='r', length_includes_head=True, label='u')
plt.arrow(0,0, 1,3, head_width=0.2, color='r', length_includes_head=True, label='v')
plt.arrow(0,0, 4,4, head_width=0.2, color='r', length_includes_head=True, label='u+v')
plt.legend()
```
This returns the following error:
```none
No handles with labels found to put in legend.
```
I'm not sure why, because, based on the documentation for plt.arrow(), label is an acceptable kwarg, and plt.legend() should ostensibly be reading that. The rest of the figure draws fine; it's just missing the legend.

Response:
It might be late but for anyone with the same issue the solution is using the method legend() for the corresponding ax not as for plt
```
fig = plt.figure()
ax = fig.add_subplot(111)
ax.spines['left'].set_position('zero')
ax.spines['right'].set_color('none')
ax.spines['bottom'].set_position('zero')
ax.spines['top'].set_color('none')
plt.axis([-5,5,-5,5])
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')
plt.grid()
plt.arrow(0,0, 3,1, head_width=0.2, color='r', length_includes_head=True, label='u')
plt.arrow(0,0, 1,3, head_width=0.2, color='r', length_includes_head=True, label='v')
plt.arrow(0,0, 4,4, head_width=0.2, color='r', length_includes_head=True, label='u+v')
ax.legend()
```


Question:
How to export figures to files from IPython Notebook I use the IPython Notebook with the --pylab inline option, since I don't want plots to show up in a different window. Now I'd like to save the plots I see in the notebook to PDF or PNG files. Some code examples use
```
import matplotlib as plt

plt.savefig("figure.png") # save as png
```
but this does not seem to work in inline mode. Of course I could simply save the PNG that is generated out of the browser, but I'd like to do this with a line of Python. I am also interested in PDF export.

Response:
try this (note that the files get saved to the default notebook folder):
```
plot(range(80))
xlabel('foo')
ylabel('bar')
legend(['myline'])
axis([0, 80, 0, 120])
savefig('sample.pdf')
```
if you want png just change it to 'sample.png'. Note that the savefig() call should be in the same notebook cell as the plotting commands.


Question:
How can I set the background color on specific areas of a figure? I've managed to plot a series of points with the following code:
```
plt = pp.figure()
for i in range(spt.shape[1]):
    spktrain = spt[0,i]
    for trial in spktrain:
        non_z = np.nonzero(trial)
        non_z = non_z[0]
        pp.plot(t[non_z], trial[non_z], 'bo')
```
I would like to place alternating bands of white and gray background on the figure in order to separate the data from each iteration of the outer for loop. In other words, I would like the data from each "spktrain" to have it's own background color (the data does not overlap). How can I go about changing the background color of a figure in a specific region?

Response:
You can use axhspan and/or axvspan like this:
```
import matplotlib.pyplot as plt

plt.figure()
plt.xlim(0, 5)
plt.ylim(0, 5)

for i in range(0, 5):
    plt.axhspan(i, i+.2, facecolor='0.2', alpha=0.5)
    plt.axvspan(i, i+.5, facecolor='b', alpha=0.5)

plt.show()
```


Question:
fill between multiple lines I would like to fill between 3 lines in matplotlib.pyplot but unfortunately the fill_between gives me opportunity to fill between only two lines. Any ideas how to deal with this? Edit: Ok, I did not explain what I really mean since I cannot add the picture with my current reputation so maybe in that way: I try to fill the polygon bounded by these lines and I have no idea how because fill_between gives me opportunity to fill only area between two of them. Below the fill equation:
```
y <= 4- 2x
y <= 3 - 1/2x
y <= 1 - x
y >= 0
x >= 0
```
the x and y bigger than 0 is obvious. I start the plot from (0,0) but I still have 3 lines...
```
y <= 4- 2x
y <= 3 - 1/2x
y <= 1 - x
```

Response:
If you start the plot in point (0, 0), and therefore do not need to consider the area of the polygon not in the first quadrant, then this should do the trick in this particular situation:
```
import matplotlib.pyplot as plt
import numpy as np

x = np.arange(0,10,0.1)

# The lines to plot
y1 = 4 - 2*x
y2 = 3 - 0.5*x
y3 = 1 -x

# The upper edge of polygon (min of lines y1 & y2)
y4 = np.minimum(y1, y2)

# Set y-limit, making neg y-values not show in plot
plt.ylim(0, 5)

# Plotting of lines
plt.plot(x, y1,
         x, y2,
         x, y3)

# Filling between line y3 and line y4
plt.fill_between(x, y3, y4, color='grey', alpha='0.5')
plt.show()
```


Question:
What is the process to create pdf reports with charts from a DB? [closed] Closed. This question is seeking recommendations for software libraries, tutorials, tools, books, or other off-site resources. It does not meet Stack Overflow guidelines. It is not currently accepting answers. We don’t allow questions seeking recommendations for software libraries, tutorials, tools, books, or other off-site resources. You can edit the question so it can be answered with facts and citations. Closed 6 months ago. The community reviewed whether to reopen this question 6 months ago and left it closed: Original close reason(s) were not resolved Improve this question I have a database generated by a survey to evaluate university professors. What I want is a python script that takes the information from that database, generates a graphing table for each user, creates graphs for each user, and then renders it in a template to export it to a pdf. What does the database look like?
```
User    Professor_evaluated  Category       Question    Answer
_________________________________________________________________
Mike    Professor Criss       respect           1         3
Mike    Professor Criss       respect           2         4
Mike    Professor Criss       wisdom            3         5
Mike    Professor Criss       wisdom            4         3
Charles Professor Criss       respect           1         3
Charles Professor Criss       respect           2         4
Charles Professor Criss       wisdom            3         5
Charles Professor Criss       wisdom            4         3
```
Each teacher has several categories assigned to be evaluated (respect, wisdom, etc.) and in turn each category has associated questions. In other words, a category has several questions. Each row of the DB is the answer to a question from a student evaluating a teacher What do I need? I need to create a script for automatically generate pdf reports that summarizes this information through charts, for example a chart with the overall score of each teacher, another chart with the score of each teacher by category, another chart with the average of each student, etc..Finally, every teacher would have a report.I want a report like this What is my question? my question is about which python packages and modules I would need to do this task. And what would be the general process of doing so. I don't need the code, because I know the answer is very general, but the knowledge of how I could do it. For example: you would first need to process the information with pandas, to create a table that summarizes the information you want to graph, then plot it, then create a template of your report with XYZ module and then export it to pdf with XYZ module.

Response:
There are a lot of options for creating a pdf in python. Some of these options are ReportLab, pydf2, pdfdocument and FPDF. The FPDF library is fairly stragihtforward to use and is what I've used in this example. FPDF Documentation can be found here. It's perhaps also good to think about what python modules you might want to use to create graphs and tables. In my example, I use matplotlib (link to docs) and I also use Pandas to create a dataframe using pandas.dataframe(). I've posted a rather lengthy but fully reproducible example below, using pandas, matplotlib and fpdf. The data are a subset of what the OP provided in the question. I loop through the dataframe in my example to create the table, but there are alternative and perhaps more efficient ways to do this.
```
import pandas as pd
import matplotlib
from pylab import title, figure, xlabel, ylabel, xticks, bar, legend, axis, savefig
from fpdf import FPDF

df = pd.DataFrame()
df['Question'] = ["Q1", "Q2", "Q3", "Q4"]
df['Charles'] = [3, 4, 5, 3]
df['Mike'] = [3, 3, 4, 4]

title("Professor Criss's Ratings by Users")
xlabel('Question Number')
ylabel('Score')

c = [2.0, 4.0, 6.0, 8.0]
m = [x - 0.5 for x in c]

xticks(c, df['Question'])

bar(m, df['Mike'], width=0.5, color="#91eb87", label="Mike")
bar(c, df['Charles'], width=0.5, color="#eb879c", label="Charles")

legend()
axis([0, 10, 0, 8])
savefig('barchart.png')

pdf = FPDF()
pdf.add_page()
pdf.set_xy(0, 0)
pdf.set_font('arial', 'B', 12)
pdf.cell(60)
pdf.cell(75, 10, "A Tabular and Graphical Report of Professor Criss's Ratings by Users Charles and Mike", 0, 2, 'C')
pdf.cell(90, 10, " ", 0, 2, 'C')
pdf.cell(-40)
pdf.cell(50, 10, 'Question', 1, 0, 'C')
pdf.cell(40, 10, 'Charles', 1, 0, 'C')
pdf.cell(40, 10, 'Mike', 1, 2, 'C')
pdf.cell(-90)
pdf.set_font('arial', '', 12)
for i in range(0, len(df)):
    pdf.cell(50, 10, '%s' % (df['Question'].iloc[i]), 1, 0, 'C')
    pdf.cell(40, 10, '%s' % (str(df.Mike.iloc[i])), 1, 0, 'C')
    pdf.cell(40, 10, '%s' % (str(df.Charles.iloc[i])), 1, 2, 'C')
    pdf.cell(-90)
pdf.cell(90, 10, " ", 0, 2, 'C')
pdf.cell(-30)
pdf.image('barchart.png', x = None, y = None, w = 0, h = 0, type = '', link = '')
pdf.output('test.pdf', 'F')
```
Expected test.pdf: Update (April 2020): I made an edit to the original answer in April 2020 to replace use of pandas.DataFrame.ix() since this is deprecated. In my example I was able to replace it's use with pandas.DataFrame.iloc and the output is the same as before.


Question: Common title to many subplots in Matplotlib [duplicate] This question already has answers here: Global legend and title aside subplots (4 answers) Closed 7 years ago. I am making a chart in matplotlib and I have many subplots in it each of them with a different title, but on the top I also want to a put a title to the whole chart. How this can be done?

Response: You can use the pyplot.suptitle command to add a centered title to the figure in addition to sub plot titles.


Question:
TypeError: Invalid dimensions for image data when plotting array with imshow() For the following code
```
# Numerical operation
SN_map_final = (new_SN_map - mean_SN) / sigma_SN

# Plot figure
fig12 = plt.figure(12)
fig_SN_final = plt.imshow(SN_map_final, interpolation='nearest')
plt.colorbar()

fig12 = plt.savefig(outname12)
```
with new_SN_map being a 1D array and mean_SN and sigma_SN being constants, I get the following error.
```
Traceback (most recent call last):
  File "c:\Users\Valentin\Desktop\Stage M2\density_map_simple.py", line 546, in <module>
    fig_SN_final = plt.imshow(SN_map_final, interpolation='nearest')
  File "c:\users\valentin\appdata\local\enthought\canopy\user\lib\site-packages\matplotlib\pyplot.py", line 3022, in imshow
    **kwargs)
  File "c:\users\valentin\appdata\local\enthought\canopy\user\lib\site-packages\matplotlib\__init__.py", line 1812, in inner
    return func(ax, *args, **kwargs)
  File "c:\users\valentin\appdata\local\enthought\canopy\user\lib\site-packages\matplotlib\axes\_axes.py", line 4947, in imshow
    im.set_data(X)
  File "c:\users\valentin\appdata\local\enthought\canopy\user\lib\site-packages\matplotlib\image.py", line 453, in set_data
    raise TypeError("Invalid dimensions for image data")
TypeError: Invalid dimensions for image data
```
What is the source of this error? I thought my numerical operations were allowed.

Response:
There is a (somewhat) related question on StackOverflow: Showing an image with pylab.imshow() Here the problem was that an array of shape (nx,ny,1) is still considered a 3D array, and must be squeezed or sliced into a 2D array. More generally, the reason for the Exception TypeError: Invalid dimensions for image data is shown here: matplotlib.pyplot.imshow() needs a 2D array, or a 3D array with the third dimension being of shape 3 or 4! You can easily check this with (these checks are done by imshow, this function is only meant to give a more specific message in case it's not a valid input):
```
from __future__ import print_function
import numpy as np

def valid_imshow_data(data):
    data = np.asarray(data)
    if data.ndim == 2:
        return True
    elif data.ndim == 3:
        if 3 <= data.shape[2] <= 4:
            return True
        else:
            print('The "data" has 3 dimensions but the last dimension '
                  'must have a length of 3 (RGB) or 4 (RGBA), not "{}".'
                  ''.format(data.shape[2]))
            return False
    else:
        print('To visualize an image the data must be 2 dimensional or '
              '3 dimensional, not "{}".'
              ''.format(data.ndim))
        return False
```
In your case:
```

```python
new_SN_map = np.array([1,2,3])
```

```python
valid_imshow_data(new_SN_map)
#Output
#To visualize an image the data must be 2 dimensional or 3 dimensional, not "1".
#False
#```
#The np.asarray is what is done internally by matplotlib.pyplot.imshow so it's generally best you do it too. If you have a numpy array it's obsolete but if not (for example a list) it's necessary. In your specific case you got a 1D array, so you need to add a dimension with np.expand_dims()
#```
#import matplotlib.pyplot as plt
#a = np.array([1,2,3,4,5])
#a = np.expand_dims(a, axis=0)  # or axis=1
#plt.imshow(a)
#plt.show()
#```
#or just use something that accepts 1D arrays like plot:
#```
#a = np.array([1,2,3,4,5])
#plt.plot(a)
#plt.show()
#```
```