Question: change scatter plot marker thickness How can you change the thickness of marker lines in a scatter plot plt.scatter()? markeredgewidth is a valid attribute in plt.plot(); is there any equivalent attribute for scatter plots? For example, when you change the size of a scatter plot (with marker = 'x'), the markers only get bigger, but the line thickness doesn't change. I'm not trying to change the size but line thickness!

Response:
you are looking for the kwarg linewidths. e.g.:
```
import matplotlib.pyplot as plt
import numpy as np
x = y = np.arange(5)

fig,ax = plt.subplots(1)

ax.scatter(x,y,  s=100,marker='x',color='b',linewidths=1)
ax.scatter(x,y+1,s=100,marker='x',color='r',linewidths=2)
ax.scatter(x,y+2,s=100,marker='x',color='g',linewidths=3)

plt.show()
```
Note: On some versions of matplotlib, it appears the kwarg is linewidth, not linewidths, despite what the manual currently says (April 2020). This is a known issue on the matplotlib github.


Question:
How to display print statements interlaced with matplotlib plots inline in Ipython? I would like to have the output of print statements interlaced with plots, in the order in which they were printed and plotted in the Ipython notebook cell. For example, consider the following code: (launching ipython with ipython notebook --no-browser --no-mathjax)
```
%matplotlib inline
import matplotlib.pyplot as plt

i = 0
for data in manydata:
    fig, ax = plt.subplots()
    print "data number i =", i
    ax.hist(data)
    i = i + 1
```
Ideally the output would look like:
```
data number i = 0
(histogram plot)
data number i = 1
(histogram plot)
...
```
However, the actual output in Ipython will look like:
```
data number i = 0
data number i = 1
...
(histogram plot)
(histogram plot)
...
```
Is there a direct solution in Ipython, or a workaround or alternate solution to get the interlaced output?

Response:
There is simple solution, use matplotlib.pyplot.show() function after plotting. this will display graph before executing next line of the code
```
%matplotlib inline
import matplotlib.pyplot as plt

i = 0
for data in manydata:
    fig, ax = plt.subplots()
    print "data number i =", i
    ax.hist(data)
    plt.show() # this will load image to console before executing next line of code
    i = i + 1
```
this code will work as requested


Question:
How to plot cdf in matplotlib in Python? I have a disordered list named d that looks like:
```
[0.0000, 123.9877,0.0000,9870.9876, ...]
```
I just simply want to plot a cdf graph based on this list by using Matplotlib in Python. But don't know if there's any function I can use
```
d = []
d_sorted = []
for line in fd.readlines():
    (addr, videoid, userag, usertp, timeinterval) = line.split()
    d.append(float(timeinterval))

d_sorted = sorted(d)

class discrete_cdf:
    def __init__(data):
        self._data = data # must be sorted
        self._data_len = float(len(data))

    def __call__(point):
        return (len(self._data[:bisect_left(self._data, point)]) /
               self._data_len)

cdf = discrete_cdf(d_sorted)
xvalues = range(0, max(d_sorted))
yvalues = [cdf(point) for point in xvalues]
plt.plot(xvalues, yvalues)
```
Now I am using this code, but the error message is :
```
Traceback (most recent call last):
File "hitratioparea_0117.py", line 43, in <module>
cdf = discrete_cdf(d_sorted)
TypeError: __init__() takes exactly 1 argument (2 given)
```

Response:
I know I'm late to the party. But, there is a simpler way if you just want the cdf for your plot and not for future calculations:
```
plt.hist(put_data_here, normed=True, cumulative=True, label='CDF',
         histtype='step', alpha=0.8, color='k')
```
As an example,
```
plt.hist(dataset, bins=bins, normed=True, cumulative=True, label='CDF DATA',
         histtype='step', alpha=0.55, color='purple')
# bins and (lognormal / normal) datasets are pre-defined
```
EDIT: This example from the matplotlib docs may be more helpful.


Question:
Stacked Bar Chart with Centered Labels I'm trying to "robustly" center the data labels in a stacked bar chart. A simple code example and the result are given below. As you can see, the data labels aren't really centered in all rectangles. What am I missing?
```
import numpy as np
import matplotlib.pyplot as plt

A = [45, 17, 47]
B = [91, 70, 72]

fig = plt.figure(facecolor="white")

ax = fig.add_subplot(1, 1, 1)
bar_width = 0.5
bar_l = np.arange(1, 4)
tick_pos = [i + (bar_width / 2) for i in bar_l]

ax1 = ax.bar(bar_l, A, width=bar_width, label="A", color="green")
ax2 = ax.bar(bar_l, B, bottom=A, width=bar_width, label="B", color="blue")
ax.set_ylabel("Count", fontsize=18)
ax.set_xlabel("Class", fontsize=18)
ax.legend(loc="best")
plt.xticks(tick_pos, ["C1", "C2", "C3"], fontsize=16)
plt.yticks(fontsize=16)

for r1, r2 in zip(ax1, ax2):
    h1 = r1.get_height()
    h2 = r2.get_height()
    plt.text(r1.get_x() + r1.get_width() / 2., h1 / 2., "%d" % h1, ha="center", va="bottom", color="white", fontsize=16, fontweight="bold")
    plt.text(r2.get_x() + r2.get_width() / 2., h1 + h2 / 2., "%d" % h2, ha="center", va="bottom", color="white", fontsize=16, fontweight="bold")

plt.show()
```

Response:
The following method is more succinct, and easily scales. Putting the data into a pandas.DataFrame is the easiest way to plot a stacked bar plot. Using pandas.DataFrame.plot.bar(stacked=True), or pandas.DataFrame.plot(kind='bar', stacked=True), is the easiest way to plot a stacked bar plot. This method returns a matplotlib.axes.Axes or a numpy.ndarray of them. Since seaborn is just a high-level API for matplotlib, these solutions also work with seaborn plots, as shown in How to annotate a seaborn barplot with the aggregated value. For horizontal stacked bars, see Horizontal stacked bar plot and add labels to each section Tested in python 3.10, pandas 1.4.2, matplotlib 3.5.1, seaborn 0.11.2 Imports & Test DataFrame
```py
import pandas as pd
import matplotlib.pyplot as plt

A = [45, 17, 47]
B = [91, 70, 72]
C = [68, 43, 13]

# pandas dataframe
df = pd.DataFrame(data={'A': A, 'B': B, 'C': C}, index=['C1', 'C2', 'C3'])

     A   B   C
C1  45  91  68
C2  17  70  43
C3  47  72  13
```
Updated for matplotlib v3.4.2 Use matplotlib.pyplot.bar_label, which will automatically center the values in the bar. See How to add value labels on a bar chart for additional details and examples with .bar_label. Tested with pandas v1.2.4, which is using matplotlib as the plot engine. If some sections of the bar plot will be zero, see my answer, which shows how to customize the labels for .bar_label(). ax.bar_label(c, fmt='%0.0f', label_type='center') will change the number format to show no decimal places, if needed.
```py
ax = df.plot(kind='bar', stacked=True, figsize=(8, 6), rot=0, xlabel='Class', ylabel='Count')
for c in ax.containers:

    # Optional: if the segment is small or 0, customize the labels
    labels = [v.get_height() if v.get_height() > 0 else '' for v in c]

    # remove the labels parameter if it's not needed for customized labels
    ax.bar_label(c, labels=labels, label_type='center')
```
Other options for removing labels for small segments can use fmt With the matplotlib 3.7 Update, the fmt argument of bar_label now accepts {}-style format strings. fmt=lambda x: f'{x:.0f}' if x > 0 else '' fmt=lambda x: np.where(x > 0, f'{x:.0f}', '') with np.where
```py
ax = df.plot(kind='bar', stacked=True, figsize=(8, 6), rot=0, xlabel='Class', ylabel='Count')
for c in ax.containers:
    ax.bar_label(c, fmt=lambda x: f'{x:.0f}' if x > 0 else '', label_type='center')
```
Seaborn Options seaborn is a high-level api for matplotlib The seaborn.barplot api doesn't have an option for stacking, but it "can" be implemented with sns.histplot, or sns.displot. Seaborn DataFrame Format
```py
# create the data frame
df = pd.DataFrame(data={'A': A, 'B': B, 'C': C, 'cat': ['C1', 'C2', 'C3']})

    A   B   C cat
0  45  91  68  C1
1  17  70  43  C2
2  47  72  13  C3

# convert the dataframe to a long form
df = df.melt(id_vars='cat')

  cat variable  value
0  C1        A     45
1  C2        A     17
2  C3        A     47
3  C1        B     91
4  C2        B     70
5  C3        B     72
6  C1        C     68
7  C2        C     43
8  C3        C     13
```
axes-level plot
```py
# plot
ax = sns.histplot(data=df, x='cat', hue='variable', weights='value', discrete=True, multiple='stack')

# iterate through each container
for c in ax.containers:

    # Optional: if the segment is small or 0, customize the labels
    labels = [v.get_height() if v.get_height() > 0 else '' for v in c]

    # remove the labels parameter if it's not needed for customized labels
    ax.bar_label(c, labels=labels, label_type='center')
```
figure-level plot
```py
# plot
g = sns.displot(data=df, x='cat', hue='variable', weights='value', discrete=True, multiple='stack')

# iterate through each axes
for ax in g.axes.flat:

    # iterate through each container
    for c in ax.containers:

        # Optional: if the segment is small or 0, customize the labels
        labels = [v.get_height() if v.get_height() > 0 else '' for v in c]

        # remove the labels parameter if it's not needed for customized labels
        ax.bar_label(c, labels=labels, label_type='center')
```
Original Answer Using the .patches method unpacks a list of matplotlib.patches.Rectangle objects, one for each of the sections of the stacked bar. Each .Rectangle has methods for extracting the various values that define the rectangle. Each .Rectangle is in order from left to right, and bottom to top, so all the .Rectangle objects, for each level, appear in order, when iterating through .patches. The labels are made using an f-string, label_text = f'{height}', so any additional text can be added as needed, such as label_text = f'{height}%' label_text = f'{height:0.0f}' will display numbers with no decimal places. Plot
```py
plt.style.use('ggplot')

ax = df.plot(stacked=True, kind='bar', figsize=(12, 8), rot='horizontal')

# .patches is everything inside of the chart
for rect in ax.patches:
    # Find where everything is located
    height = rect.get_height()
    width = rect.get_width()
    x = rect.get_x()
    y = rect.get_y()

    # The height of the bar is the data value and can be used as the label
    label_text = f'{height}'  # f'{height:.2f}' to format decimal values

    # ax.text(x, y, text)
    label_x = x + width / 2
    label_y = y + height / 2

    # plot only when height is greater than specified value
    if height > 0:
        ax.text(label_x, label_y, label_text, ha='center', va='center', fontsize=8)

ax.legend(bbox_to_anchor=(1.05, 1), loc='upper left', borderaxespad=0.)
ax.set_ylabel("Count", fontsize=18)
ax.set_xlabel("Class", fontsize=18)
plt.show()
```
To plot a horizontal bar: kind='barh' label_text = f'{width}' if width > 0: Attribution: jsoma/chart.py


Question:
decompose() for time series: ValueError: You must specify a period or x must be a pandas object with a DatetimeIndex with a freq not set to None I have some problems executing an additive model right. I have the following data frame: And when I run this code:
```py
import statsmodels as sm
import statsmodels.api as sm
decomposition = sm.tsa.seasonal_decompose(df, model = 'additive')
fig = decomposition.plot()
matplotlib.rcParams['figure.figsize'] = [9.0,5.0]
```
I got that message: ValueError: You must specify a period or x must be a pandas object with a >DatetimeIndex with a freq not set to None What should I do in order to get that example: The screen above I took from this place

Response:
Having the same ValueError, this is just the result of some testing and little research on my own, without the claim to be complete or professional about it. Please comment or answer whoever finds something wrong. Of course, your data should be in the right order of the index values, which you would assure with df.sort_index(inplace=True), as you state it in your answer. This is not wrong as such, though the error message is not about the sort order, and I have checked this: the error does not go away in my case when I sort the index of a huge dataset I have at hand. It is true, I also have to sort the df.index, but the decompose() can handle unsorted data as well where items jump here and there in time: then you simply get a lot of blue lines from left to the right and back, until the whole graph is full of it. What is more, usually, the sorting is already in the right order anyway. In my case, sorting does not help fixing the error. Thus I also doubt that index sorting has fixed the error in your case, because: what does the error actually say? ValueError: You must specify: [either] a period or x must be a pandas object with a DatetimeIndex with a freq not set to None Before all, in case you have a list column so that your time series is nested up to now, see Convert pandas df with data in a "list column" into a time series in long format. Use three columns: [list of data] + [timestamp] + [duration] for details how to unnest a list column. This would be needed for both 1.) and 2.). Details of 1.: "You must specify [either] a period ..." Definition of period "period, int, optional" from https://www.statsmodels.org/stable/generated/statsmodels.tsa.seasonal.seasonal_decompose.html: Period of the series. Must be used if x is not a pandas object or if the index of x does not have a frequency. Overrides default periodicity of x if x is a pandas object with a timeseries index. The period parameter that is set with an integer means the number of cycles which you expect to be in the data. If you have a df with 1000 rows with a list column in it (call it df_nested), and each list with for example 100 elements, then you will have 100 elements per cycle. It is probably smart taking period = len(df_nested) (= number of cycles) in order to get the best split of seasonality and trend. If your elements per cycle vary over time, other values may be better. I am not sure about how to rightly set the parameter, therefore the question statsmodels seasonal_decompose(): What is the right “period of the series” in the context of a list column (constant vs. varying number of items) on Cross Validated which is not yet answered. The "period" parameter of option 1.) has a big advantage over option 2.). Though it uses the time index (DatetimeIndex) for its x-axis, it does not require an item to hit the frequency exactly, in contrast to option 2.). Instead, it just joins together whatever is in a row, with the advantage that you do not need to fill any gaps: the last value of the previous event is just joined with the next value of the following event, whether it is already in the next second or on the next day. What is the max possible "period" value? In case you have a list column (call the df "df_nested" again), you should first unnest the list column to a normal column. The max period is len(df_unnested)/2. Example1: 20 items in x (x is the amount of all items of df_unnested) can maximally have a period = 10. Example2: Having the 20 items and taking period=20 instead, this throws the following error: ValueError: x must have 2 complete cycles requires 40 observations. x only has 20 observation(s) Another side-note: To get rid of the error in question, period = 1 should already take it away, but for time series analysis, "=1" does not reveal anything new, every cycle is just 1 item then, the trend is the same as the original data, the seasonality is 0, and the residuals are always 0. #### Example borrowed from Convert pandas df with data in a "list column" into a time series in long format. Use three columns: [list of data] + [timestamp] + [duration]
```
df_test = pd.DataFrame({'timestamp': [1462352000000000000, 1462352100000000000, 1462352200000000000, 1462352300000000000],
                'listData': [[1,2,1,9], [2,2,3,0], [1,3,3,0], [1,1,3,9]],
                'duration_sec': [3.0, 3.0, 3.0, 3.0]})
tdi = pd.DatetimeIndex(df_test.timestamp)
df_test.set_index(tdi, inplace=True)
df_test.drop(columns='timestamp', inplace=True)
df_test.index.name = 'datetimeindex'

df_test = df_test.explode('listData')
sizes = df_test.groupby(level=0)['listData'].transform('size').sub(1)
duration = df_test['duration_sec'].div(sizes)
df_test.index += pd.to_timedelta(df_test.groupby(level=0).cumcount() * duration, unit='s')
```
The resulting df_test['listData'] looks as follows:
```
2016-05-04 08:53:20    1
2016-05-04 08:53:21    2
2016-05-04 08:53:22    1
2016-05-04 08:53:23    9
2016-05-04 08:55:00    2
2016-05-04 08:55:01    2
2016-05-04 08:55:02    3
2016-05-04 08:55:03    0
2016-05-04 08:56:40    1
2016-05-04 08:56:41    3
2016-05-04 08:56:42    3
2016-05-04 08:56:43    0
2016-05-04 08:58:20    1
2016-05-04 08:58:21    1
2016-05-04 08:58:22    3
2016-05-04 08:58:23    9
```
Now have a look at different period's integer values. period = 1:
```
result_add = seasonal_decompose(x=df_test['listData'], model='additive', extrapolate_trend='freq', period=1)
plt.rcParams.update({'figure.figsize': (5,5)})
result_add.plot().suptitle('Additive Decompose', fontsize=22)
plt.show()
```
period = 2:
```
result_add = seasonal_decompose(x=df_test['listData'], model='additive', extrapolate_trend='freq', period=2)
plt.rcParams.update({'figure.figsize': (5,5)})
result_add.plot().suptitle('Additive Decompose', fontsize=22)
plt.show()
```
If you take a quarter of all items as one cycle which is 4 (out of 16 items) here. period = 4:
```
result_add = seasonal_decompose(x=df_test['listData'], model='additive', extrapolate_trend='freq', period=int(len(df_test)/4))
plt.rcParams.update({'figure.figsize': (5,5)})
result_add.plot().suptitle('Additive Decompose', fontsize=22)
plt.show()
```
Or if you take the max possible size of a cycle which is 8 (out of 16 items) here. period = 8:
```
result_add = seasonal_decompose(x=df_test['listData'], model='additive', extrapolate_trend='freq', period=int(len(df_test)/2))
plt.rcParams.update({'figure.figsize': (5,5)})
result_add.plot().suptitle('Additive Decompose', fontsize=22)
plt.show()
```
Have a look at how the y-axes change their scale. #### You will increase the period integer according to your needs. The max in your case of the question:
```
sm.tsa.seasonal_decompose(df, model = 'additive', period = int(len(df)/2))
```
Details of 2.: "... or x must be a pandas object with a DatetimeIndex with a freq not set to None" To get x to be a DatetimeIndex with a freq not set to None, you need to assign the freq of the DatetimeIndex using .asfreq('?') with ? being your choice among a wide range of offset aliases from https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#offset-aliases. In your case, this option 2. is the better suited as you seem to have a list without gaps. Your monthly data then should probably be introduced as "month start frequency" --> "MS" as offset alias:
```
sm.tsa.seasonal_decompose(df.asfreq('MS'), model = 'additive')
```
See How to set frequency with pd.to_datetime()? for more details, also about how you would deal with gaps. If you have data that is highly scattered in time so that you have too many gaps to fill or if gaps in time are nothing important, option 1 of using "period" is probably the better choice. In my example case of df_test, option 2. is not good. The data is totally scattered in time, and if I take a second as the frequency, you get this: Output of df_test.asfreq('s') (=frequency in seconds):
```
2016-05-04 08:53:20      1
2016-05-04 08:53:21      2
2016-05-04 08:53:22      1
2016-05-04 08:53:23      9
2016-05-04 08:53:24    NaN
                      ...
2016-05-04 08:58:19    NaN
2016-05-04 08:58:20      1
2016-05-04 08:58:21      1
2016-05-04 08:58:22      3
2016-05-04 08:58:23      9
Freq: S, Name: listData, Length: 304, dtype: object
```
You see here that although my data is only 16 rows, introducing a frequency in seconds forces the df to be 304 rows only to reach out from "08:53:20" till "08:58:23", 288 gaps are caused here. What is more, here you have to hit the exact time. If you have 0.1 or even 0.12314 seconds as your real frequency instead, you will not hit most of the items with your index. Here an example with min as the offset alias, df_test.asfreq('min'):
```
2016-05-04 08:53:20      1
2016-05-04 08:54:20    NaN
2016-05-04 08:55:20    NaN
2016-05-04 08:56:20    NaN
2016-05-04 08:57:20    NaN
2016-05-04 08:58:20      1
```
We see that only the first and the last minute are filled at all, the rest is not hit. Taking the day as as the offset alias, df_test.asfreq('d'):
```
2016-05-04 08:53:20    1
```
We see that you get only the first row as the resulting df, since there is only one day covered. It will give you the first item found, the rest is dropped. The end of it all Putting together all of this, in your case, take option 2., while in my example case of df_test, option 1 is needed.


Question:
matplotlib embed figures in auto generated html [duplicate] This question already has answers here: Dynamically serving a matplotlib image to the web using python (6 answers) Closed 7 years ago. I want to embed a figure generated by python matplotlib into a html file with other content. Is that possible? What I have thought is saving figures as png file and then use  tag to refer to it. Some code I was trying to use are like:
```
import matplotlib.pyplot as plt
fig = plt.figure()
#plot sth
plt.savefig('test.png')

html = 'Some html head' + '<img src=\'test.png\'>' + 'Some more html'

with open('test.html','w') as f:
    f.write(html)
```
However, this will generate two files instead of one and I don't have a server to host the png file. Is that possible to embed the figure in the html? How do I do it in python. Thank you.

Response:
You can write the image into a temporary file and encode it with base64 and then embed the encoded base64 image into your html. Most modern browsers will correctly render the image. A short example modified from your code will be:
```
import matplotlib.pyplot as plt
import base64
from io import BytesIO

fig = plt.figure()
#plot sth

tmpfile = BytesIO()
fig.savefig(tmpfile, format='png')
encoded = base64.b64encode(tmpfile.getvalue()).decode('utf-8')

html = 'Some html head' + '<img src=\'data:image/png;base64,{}\'>'.format(encoded) + 'Some more html'

with open('test.html','w') as f:
    f.write(html)
```


Question:
Exponential curve fitting in SciPy I have two NumPy arrays x and y. When I try to fit my data using exponential function and curve_fit (SciPy) with this simple code
```
#!/usr/bin/env python
from pylab import *
from scipy.optimize import curve_fit

x = np.array([399.75, 989.25, 1578.75, 2168.25, 2757.75, 3347.25, 3936.75, 4526.25, 5115.75, 5705.25])
y = np.array([109,62,39,13,10,4,2,0,1,2])

def func(x, a, b, c, d):
    return a*np.exp(b-c*x)+d

popt, pcov = curve_fit(func, x, y)
```
I get wrong coefficients popt
```
[a,b,c,d] = [1., 1., 1., 24.19999988]
```
What is the problem?

Response:
First comment: since a*exp(b - c*x) = (a*exp(b))*exp(-c*x) = A*exp(-c*x), a or b is redundant. I'll drop b and use:
```
import matplotlib.pyplot as plt

def func(x, a, c, d):
    return a*np.exp(-c*x)+d
```
That isn't the main issue. The problem is simply that curve_fit fails to converge to a solution to this problem when you use the default initial guess (which is all 1s). Check pcov; you'll see that it is inf. This is not surprising, because if c is 1, most of the values of exp(-c*x) underflow to 0:
```

```python
np.exp(-x)
#Output
#array([  2.45912644e-174,   0.00000000e+000,   0.00000000e+000,
#         0.00000000e+000,   0.00000000e+000,   0.00000000e+000,
#         0.00000000e+000,   0.00000000e+000,   0.00000000e+000,
#         0.00000000e+000])
#```
#This suggests that c should be small. A better initial guess is, say, p0 = (1, 1e-6, 1). Then I get:
#```
```

```python
popt, pcov = curve_fit(func, x, y, p0=(1, 1e-6, 1))
```

```python
popt
#Output
#array([  1.63561656e+02,   9.71142196e-04,  -1.16854450e+00])
#```
#This looks reasonable:
#```
```

```python
xx = np.linspace(300, 6000, 1000)
```

```python
yy = func(xx, *popt)
```

```python
plt.plot(x, y, 'ko')
#Output
#[<matplotlib.lines.Line2D at 0x41c5ad0>]
```

```python
plt.plot(xx, yy)
#Output
#[<matplotlib.lines.Line2D at 0x41c5c10>]
#```
```


Question:
Invert an axis in a matplotlib grafic How can I invert the y_axis? Z is a np.array.Thank you
```
Z=TempLake

X,Y=np.meshgrid(range(Z.shape[0]+1),range(Z.shape[1]+1))
im = plt.pcolormesh(X,Y,Z.transpose(), cmap='hot')
plt.colorbar(im, orientation='horizontal')
plt.show()
```
I have this: I need this:

Response:
As @Chris said, this can be done with:
```
ax = plt.gca()
ax.invert_yaxis()
```
Before the 'plt.show()'.


Question:
Clearing a subplot in Matplotlib I have a number of subplots in a figure fig1, created via
```
ax = fig1.add_subplot(221)
```
I then plot stuff in each of the subplots via
```
im=ax.plot(x,y)
```
and add some axis labels via
```
ax.set_xlabel('xlabel')
```
I would then like to clear a specific subplot completely, as described in When to use cla(), clf() or close() for clearing a plot in matplotlib?. However the problem is that ax.cla()and ax.clear() seem to only clear the data from the plot, without removing the axes, axis tick labels etc. On the other hand plt.clf() clears the entire figure. Is there something in between? A clf-like command that clears everything in a subplot, including axis labels? Or have I simply used the commands in a wrong way?

Response:
ax.clear() clears the axes. That is, it removes all settings and data from the axes such that you are left with an axes, just as it had been just created. ax.axis("off") turns the axes off, such that all axes spines and ticklabels are hidden. ax.set_visible(False) turns the complete axes invisible, including the data that is in it. ax.remove() removes the axes from the figure. Complete example:
```
import matplotlib.pyplot as plt

fig,axes = plt.subplots(2,3)
for ax in axes.flat:
    ax.plot([2,3,1])

axes[0,1].clear()
axes[1,0].axis("off")
axes[1,1].set_visible(False)
axes[0,2].remove()

plt.show()
```


Question:
How to repress scientific notation in factorplot y-axis Simple example below for this issue which I just can't solve. N.B. Some other Seaborn plotting methods seems to have arguments to repress the exponential form but seemingly not factorplots. I tried some Matplotlib solutions including those suggested in this similar question but none work. Also this is not a dupe of this question. I use factorplots very frequently and ideally want to find a proper solution as opposed to a workaround.
```
data = {'reports': [4, 24, 31, 2, 3],'coverage': [35050800, 54899767, 57890789, 62890798, 70897871]}
df = pd.DataFrame(data)
df
```
Produces this dataframe:
```
coverage    reports
0   35050800    4
1   54899767    24
2   57890789    31
3   62890798    2
4   70897871    3
```
And then this Seaborn code:
```
sns.factorplot(y="coverage", x="reports", kind='bar', data=df, label="Total")
```
Produces this plot: Is there a way to get the y axis to display an appropriate numeric scale based on the coverage values?

Response:
It looks like the following line solves the issue:
```
plt.ticklabel_format(style='plain', axis='y')
```
Here is the documentation link.


Question:
Getting empty tick labels before showing a plot in Matplotlib I'm experiencing a similar issue to the one reported here. I don't understand why the tick label text is an empty string:
```
import numpy as np
import matplotlib.pyplot as plt

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

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

labels = ax.get_xticklabels()
for label in labels:
    print(label)

plt.show()
```
Output:
```
Text(0,0,'')
Text(0,0,'')
Text(0,0,'')
Text(0,0,'')
Text(0,0,'')
Text(0,0,'')
Text(0,0,'')
Text(0,0,'')
```
I get the same result with ax.xaxis.get_ticklabels() but the plotted graph shows eight labelled ticks on the x-axis when saved or shown. However, if I ask for the labels after I show the plot, then the labels list is properly populated. Of course, it's a bit late to do anything about changing them then.
```
fig, ax = plt.subplots()
ax.plot(x,y)
plt.show()

labels = ax.get_xticklabels()
for label in labels:
    print(label)
```
Output:
```
Text(0,0,'0')
Text(1,0,'1')
Text(2,0,'2')
Text(3,0,'3')
Text(4,0,'4')
Text(5,0,'5')
Text(6,0,'6')
Text(7,0,'7')
```
Why does this happen (Mac OS X Yosemite, Matplotlib 1.5.1) and how can I get my labels before I show or save my plot?

Response:
You've correctly identified the problem: before you call plt.show() nothing is explicitly set. This is because matplotlib avoids static positioning of the ticks unless it has to, because you're likely to want to interact with it: if you can ax.set_xlim() for example. In your case, you can draw the figure canvas with fig.canvas.draw() to trigger tick positioning, so you can retrieve their value. Alternatively, you can explicity set the xticks that will in turn set the the axis to FixedFormatter and FixedLocator and achieve the same result.
```
import numpy as np
import matplotlib.pyplot as plt

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

fig, ax = plt.subplots()

ax.plot(x,y)
ax.set_xlim(0,6)

# Must draw the canvas to position the ticks
fig.canvas.draw()
# Or Alternatively
#ax.set_xticklabels(ax.get_xticks())

labels = ax.get_xticklabels()
for label in labels:
    print(label.get_text())

plt.show()

Out:
0
1
2
3
4
5
6
```


Question:
Rotating axes label text in 3D How do I rotate the z-label so the text reads (bottom => top), rather than (top => bottom)?
```
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.set_zlabel('label text flipped', rotation=90)
ax.azim = 225
plt.show()
```
I want this to hold no matter what my ax.azim setting is. This seems to be an old feature request on github but there isn't a work on it. Is there a workaround?

Response:
As a workaround, you could set the direction of the z-label manually by:
```
ax.zaxis.set_rotate_label(False)  # disable automatic rotation
ax.set_zlabel('label text', rotation=90)
```
Please note that the direction of your z-label also depends on your viewpoint, e.g:
```
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

fg = plt.figure(1); fg.clf()
axx = [fg.add_subplot(4,1,1+i, projection='3d') for i in range(4)]
for ax,azel in zip(axx, [(115,10), (115,-10), (-115,10), (-115,-10)]):
    ax.set_title(u"Azim, elev = {}°, {}°".format(*azel))
    ax.set_zlabel('label text')
    ax.azim, ax.elev = azel

fg.canvas.draw()
plt.show()
```
gives Update: It is also possible, to adjust the z-label direction of a plot, which is already drawn (but not beforehand). This is the adjusted version to modify the labels:
```
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

fg = plt.figure(1); fg.clf()
axx = [fg.add_subplot(4,1,1+i, projection='3d') for i in range(4)]
for ax,azel in zip(axx, [(115,10), (115,-10), (-115,10), (-115,-10)]):
    ax.set_title(u"Azim, elev = {}°, {}°".format(*azel))
    ax.set_zlabel('label text')
    ax.azim, ax.elev = azel
fg.canvas.draw()  # the angles of the text are calculated here

# Read drawn z-label rotations and switch them if needed
for ax in axx:
   ax.zaxis.set_rotate_label(False)
   a = ax.zaxis.label.get_rotation()
   if a<180:
       a += 180
   ax.zaxis.label.set_rotation(a)
   a = ax.zaxis.label.get_rotation() # put the actual angle in the z-label
   ax.set_zlabel(u'z-rot = {:.1f}°'.format(a))
fg.canvas.draw()

plt.show()
```


Question:
FacetGrid change titles I am trying to create a FacetGrid in Seaborn My code is currently:
```
g = sns.FacetGrid(df_reduced, col="ActualExternal", margin_titles=True)
bins = np.linspace(0, 100, 20)
g.map(plt.hist, "ActualDepth", color="steelblue", bins=bins, width=4.5)
```
This gives my the Figure Now, instead of "ActualExternal = 0.0" and "ActualExternal = 1.0", I would like the titles "Internal" and "External" And, instead of "ActualDepth" I would like the xlabel to say "Percentage Depth" Finally, I would like to add a ylabel of "Number of Defects".

Response:
Although you can iterate through the axes and set the titles individually using matplotlib commands, it is cleaner to use seaborn's built-in tools to control the title. For example:
```
# Add a column of appropriate labels
df_reduced['measure'] = df_reduced['ActualExternal'].replace({0: 'Internal',
                                                              1: 'External'}

g = sns.FacetGrid(df_reduced, col="measure", margin_titles=True)
g.map(plt.hist, "ActualDepth", color="steelblue", bins=bins, width=4.5)

# Adjust title and axis labels directly
g.set_titles("{col_name}")  # use this argument literally
g.set_axis_labels(x_var="Percentage Depth", y_var="Number of Defects")
```
This has the benefit of not needing modification regardless of whether you have 1D or 2D facets.


Question:
Hide contour linestroke on pyplot.contourf to get only fills I have a pet project to create images of maps, where I draw the roads and other stuff over a contour plot of the terrain elevation. It is intended to plan mountain bike routes (I have made some vectorial drawings by hand, in the past, and they work great for visualization). Currently, I download Digital Elevation Model, in GeoTIFF, from here: http://www.ecologia.ufrgs.br/labgeo/arquivos/downloads/dados/SRTM/geotiff/rs.rar and then create the plot with GDAL and Matplotlib contourf function:
```
from osgeo import gdal
import matplotlib
import matplotlib.pyplot as plt
from pylab import cm
import numpy

f = 'rs.tif'

elev = gdal.Open(f)

a = elev.GetRasterBand(1).ReadAsArray()

w = elev.RasterXSize
h = elev.RasterYSize
print w, h

altura  = (0.35, 0.42)
largura = (0.70, 0.82)

a = a[int(h*altura[0]):int(h*altura[1]),
      int(w*largura[0]):int(w*largura[1])]

cont = plt.contourf(a, origin='upper', cmap=cm.gist_earth, levels=numpy.arange(0,1000,20))
plt.title('Altitudes - max: %d m; min: %d m' % (numpy.amax(a), numpy.amin(a)))
plt.show()
```
Which gives: The problem is that contour lines are "white", and generate some visual pollution, which is undesired since I want to plot roads and rivers later. So, I am trying to modify the way contourf create these lighter lines, either via parameter setting, or via hack (changing source code), similar to the one proposed here: How to format contour lines from Matplotlib Also, if anyone knows how to generate such a map in a more elegant way, using other libraries, I would appreciate the tip very much! Thanks for reading.

Response:
I finally found a proper solution to this long-standing problem (currently in Matplotlib 3), which does not require multiple calls to contour or rasterize the figure. Note that the problem illustrated in the question appears only in saved publication-quality figures formats like PDF, not in lower-quality raster files like PNG. My solution was inspired by this answer, related to a similar problem with the colorbar. A similar solution turns out to solve the contour plot as well, as follows:
```
import numpy as np
import matplotlib.pyplot as plt

np.random.seed(123)
x, y = np.random.uniform(size=(100, 2)).T
z = np.exp(-x**2 - y**2)
levels = np.linspace(0, 1, 100)

cnt = plt.tricontourf(x, y, z, levels=levels, cmap="ocean")

# This is the fix for the white lines between contour levels
cnt.set_edgecolor("face")

plt.savefig("test.pdf")
```
Here below is an example of contours before the fix And here below is the same figure after the above fix


Question:
Grouped Bar graph Pandas I have a table in a pandas DataFrame named df:
```
+--- -----+------------+-------------+----------+------------+-----------+
|avg_views| avg_orders | max_views   |max_orders| min_views  |min_orders |
+---------+------------+-------------+----------+------------+-----------+
| 23       | 123       |   135       | 500      |    3       |    1      |
+---------+------------+-------------+----------+------------+-----------+
```
What I am looking for now is to plot a grouped bar graph which shows me (avg, max, min) of views and orders in one single bar chart. i.e on x axis there would be Views and orders separated by a distance and 3 bars of (avg, max, min) for views and similarly for orders. I have attached a sample bar graph image, just to know how the bar graph should look. Green color should be for avg, yellow for max and pink for avg. I took the following code from setting spacing between grouped bar plots in matplotlib but it is not working for me:
```
plt.figure(figsize=(13, 7), dpi=300)

groups = [[23, 135, 3], [123, 500, 1]]
group_labels = ['views', 'orders']
num_items = len(group_labels)
ind = np.arange(num_items)
margin = 0.05
width = (1. - 2. * margin) / num_items

s = plt.subplot(1, 1, 1)
for num, vals in enumerate(groups):
    print 'plotting: ', vals
    # The position of the xdata must be calculated for each of the two data
    # series.
    xdata = ind + margin + (num * width)
    # Removing the "align=center" feature will left align graphs, which is
    # what this method of calculating positions assumes.
    gene_rects = plt.bar(xdata, vals, width)
s.set_xticks(ind + 0.5)
s.set_xticklabels(group_labels)
```
plotting: [23, 135, 3] ... ValueError: shape mismatch: objects cannot be broadcast to a single shape

Response:
Using pandas:
```
import pandas as pd

groups = [[23,135,3], [123,500,1]]
group_labels = ['views', 'orders']

# Convert data to pandas DataFrame.
df = pd.DataFrame(groups, index=group_labels).T

# Plot.
pd.concat(
    [
        df.mean().rename('average'),
        df.min().rename('min'),
        df.max().rename('max')
    ],
    axis=1,
).plot.bar()
```


Question:
Merge subplots with shared x-axis I have two graphs to where both have the same x-axis, but with different y-axis scalings. The plot with regular axes is the data with a trend line depicting a decay while the y semi-log scaling depicts the accuracy of the fit.
```
fig1 = plt.figure(figsize=(15,6))
ax1 = fig1.add_subplot(111)

# Plot of the decay model
ax1.plot(FreqTime1,DecayCount1, '.', color='mediumaquamarine')

# Plot of the optimized fit
ax1.plot(x1, y1M, '-k', label='Fitting Function: $f(t) = %.3f e^{%.3f\t} \
         %+.3f$' % (aR1,kR1,bR1))

ax1.set_xlabel('Time (sec)')
ax1.set_ylabel('Count')
ax1.set_title('Run 1 of Cesium-137 Decay')

# Allows me to change scales
# ax1.set_yscale('log')
ax1.legend(bbox_to_anchor=(1.0, 1.0), prop={'size':15}, fancybox=True, shadow=True)
```
Now, i'm trying to figure out to implement both close together like the examples supplied by this link http://matplotlib.org/examples/pylab_examples/subplots_demo.html In particular, this one When looking at the code for the example, i'm a bit confused on how to implant 3 things: 1) Scaling the axes differently 2) Keeping the figure size the same for the exponential decay graph but having a the line graph have a smaller y size and same x size. For example: 3) Keeping the label of the function to appear in just only the decay graph. Any help would be most appreciated.

Response:
Look at the code and comments in it:
```
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import gridspec

# Simple data to display in various forms
x = np.linspace(0, 2 * np.pi, 400)
y = np.sin(x ** 2)

fig = plt.figure()
# set height ratios for subplots
gs = gridspec.GridSpec(2, 1, height_ratios=[2, 1])

# the first subplot
ax0 = plt.subplot(gs[0])
# log scale for axis Y of the first subplot
ax0.set_yscale("log")
line0, = ax0.plot(x, y, color='r')

# the second subplot
# shared axis X
ax1 = plt.subplot(gs[1], sharex = ax0)
line1, = ax1.plot(x, y, color='b', linestyle='--')
plt.setp(ax0.get_xticklabels(), visible=False)
# remove last tick label for the second subplot
yticks = ax1.yaxis.get_major_ticks()
yticks[-1].label1.set_visible(False)

# put legend on first subplot
ax0.legend((line0, line1), ('red line', 'blue line'), loc='lower left')

# remove vertical gap between subplots
plt.subplots_adjust(hspace=.0)
plt.show()
```


Question: how to annotate heatmap with text in matplotlib I am plotting a heatmap in matplotlib using: plt.pcolor(rand(5,5)) how can I annotate the heatmap with the actual numbers plotted? meaning in each cell of the plotted heatmap, put the value corresponding to that cell in the 5x5 matrix passed to pcolor. thanks.

Response:
There is no automatic feature to do such a thing, but you could loop through each point and put text in the appropriate location:
```
import matplotlib.pyplot as plt
import numpy as np

data = np.random.rand(5, 4)
heatmap = plt.pcolor(data)

for y in range(data.shape[0]):
    for x in range(data.shape[1]):
        plt.text(x + 0.5, y + 0.5, '%.4f' % data[y, x],
                 horizontalalignment='center',
                 verticalalignment='center',
                 )

plt.colorbar(heatmap)

plt.show()
```
HTH


Question:
Discrete legend in seaborn heatmap plot I am using the data present here to construct this heat map using seaborn and pandas. Code:
```
import pandas
    import seaborn.apionly as sns

    # Read in csv file
    df_trans = pandas.read_csv('LUH2_trans_matrix.csv')

    sns.set(font_scale=0.8)
    cmap = sns.cubehelix_palette(start=2.8, rot=.1, light=0.9, as_cmap=True)
    cmap.set_under('gray')  # 0 values in activity matrix are shown in gray (inactive transitions)
    df_trans = df_trans.set_index(['Unnamed: 0'])
    ax = sns.heatmap(df_trans, cmap=cmap, linewidths=.5, linecolor='lightgray')

    # X - Y axis labels
    ax.set_ylabel('FROM')
    ax.set_xlabel('TO')

    # Rotate tick labels
    locs, labels = plt.xticks()
    plt.setp(labels, rotation=0)
    locs, labels = plt.yticks()
    plt.setp(labels, rotation=0)

    # revert matplotlib params
    sns.reset_orig()
```
As you can see from csv file, it contains 3 discrete values: 0, -1 and 1. I want a discrete legend instead of the colorbar. Labeling 0 as A, -1 as B and 1 as C. How can I do that?

Response:
Well, there's definitely more than one way to accomplish this. In this case, with only three colors needed, I would pick the colors myself by creating a LinearSegmentedColormap instead of generating them with cubehelix_palette. If there were enough colors to warrant using cubehelix_palette, I would define the segments on colormap using the boundaries option of the cbar_kws parameter. Either way, the ticks can be manually specified using set_ticks and set_ticklabels. The following code sample demonstrates the manual creation of LinearSegmentedColormap, and includes comments on how to specify boundaries if using a cubehelix_palette instead.
```
import matplotlib.pyplot as plt
import pandas
import seaborn.apionly as sns
from matplotlib.colors import LinearSegmentedColormap

sns.set(font_scale=0.8)
dataFrame = pandas.read_csv('LUH2_trans_matrix.csv').set_index(['Unnamed: 0'])

# For only three colors, it's easier to choose them yourself.
# If you still really want to generate a colormap with cubehelix_palette instead,
# add a cbar_kws={"boundaries": linspace(-1, 1, 4)} to the heatmap invocation
# to have it generate a discrete colorbar instead of a continous one.
myColors = ((0.8, 0.0, 0.0, 1.0), (0.0, 0.8, 0.0, 1.0), (0.0, 0.0, 0.8, 1.0))
cmap = LinearSegmentedColormap.from_list('Custom', myColors, len(myColors))

ax = sns.heatmap(dataFrame, cmap=cmap, linewidths=.5, linecolor='lightgray')

# Manually specify colorbar labelling after it's been generated
colorbar = ax.collections[0].colorbar
colorbar.set_ticks([-0.667, 0, 0.667])
colorbar.set_ticklabels(['B', 'A', 'C'])

# X - Y axis labels
ax.set_ylabel('FROM')
ax.set_xlabel('TO')

# Only y-axis labels need their rotation set, x-axis labels already have a rotation of 0
_, labels = plt.yticks()
plt.setp(labels, rotation=0)

plt.show()
```


Question:
Animating "growing" line plot I want to produce a set of frames that can be used to animate a plot of a growing line. In the past, I have always used plt.draw() and set_ydata() to redraw the y-data as it changed over time. This time, I wish to draw a "growing" line, moving across the graph with time. Because of this, set_ydata doesn't work (xdata is changing length). For example,
```
import numpy as np
import matplotlib.pyplot as plt

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

plt.figure()
for n in range(len(x)):
    plt.plot(x[:n], y[:n], color='k')
    plt.axis([0, 10, 0, 1])
    plt.savefig('Frame%03d.png' %n)
```
While this works, it becomes very slow as it scales. Is there a faster way to do this?

Response:
A couple of notes: First off, the reason that things become progressively slower is that you're drawing more and more and more overlapping lines in the same position. A quick fix is to clear the plot each time:
```
import numpy as np
import matplotlib.pyplot as plt

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

plt.figure()
for n in range(len(x)):
    plt.cla()
    plt.plot(x[:n], y[:n], color='k')
    plt.axis([0, 10, 0, 1])
    plt.savefig('Frame%03d.png' %n)
```
Better yet, however, update both the x and y data at the same time:
```
import numpy as np
import matplotlib.pyplot as plt

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

fig, ax = plt.subplots()
line, = ax.plot(x, y, color='k')

for n in range(len(x)):
    line.set_data(x[:n], y[:n])
    ax.axis([0, 10, 0, 1])
    fig.canvas.draw()
    fig.savefig('Frame%03d.png' %n)
```
And if you'd like to use the animation module (side note: blit=True may not work properly on some backends (e.g. OSX), so try blit=False if you have issues):
```
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

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

fig, ax = plt.subplots()
line, = ax.plot(x, y, color='k')

def update(num, x, y, line):
    line.set_data(x[:num], y[:num])
    line.axes.axis([0, 10, 0, 1])
    return line,

ani = animation.FuncAnimation(fig, update, len(x), fargs=[x, y, line],
                              interval=25, blit=True)
ani.save('test.gif')
plt.show()
```


Question:
Python: A4 size for a plot I have a code that saves a figure with:
```
savefig("foo.eps", orientation = 'portrait', format = 'eps')
```
If I don't specify anythingelse, the figure is correctly saved but when I print it, the figure fills only the half of a A4 sheet.If I modify the string as:
```
savefig("foo.eps", papertype = 'a4', orientation = 'portrait', format = 'eps')
```
Nothing chages! How can I set the size of the figure in a way that it fills the whole A4 sheet? Many thanks in advance.

Response:
Try to set the size of the figure (in inches) before you save it. You can do this when you initialize the figure by doing:
```
figure(figsize=(11.69,8.27)) # for landscape
```
or if the figure exists:
```
f = gcf()  # f = figure(n) if you know the figure number
f.set_size_inches(11.69,8.27)
```
or in advance for all plots, using
```
rc('figure', figsize=(11.69,8.27))
```


Question:
Lines to separate groups in seaborn heatmap I am plotting data as a Seaborn heatmap in Python. My data is intrinsically grouped into categories, and I'd like to have lines on the plot to indicate where the groups lie on the map. As a simple example, suppose I wanted to modify this plot from the documentation...
```
import seaborn as sns; sns.set()
flights = sns.load_dataset("flights")
flights = flights.pivot("month", "year", "passengers")
ax = sns.heatmap(flights, cbar=False)
```
Where I wanted to emphasize the comparisons between quarters of the year by making a plot like the one below; how would I do that?

Response: You want ax.hlines: ax.hlines([3, 6, 9], *ax.get_xlim())


Question:
How to plot a density map in python? I have a .txt file containing the x,y values of regularly spaced points in a 2D map, the 3rd coordinate being the density at that point.
```
4.882812500000000E-004  4.882812500000000E-004  0.9072267
1.464843750000000E-003  4.882812500000000E-004   1.405174
2.441406250000000E-003  4.882812500000000E-004   24.32851
3.417968750000000E-003  4.882812500000000E-004   101.4136
4.394531250000000E-003  4.882812500000000E-004   199.1388
5.371093750000000E-003  4.882812500000000E-004   1278.898
6.347656250000000E-003  4.882812500000000E-004   1636.955
7.324218750000000E-003  4.882812500000000E-004   1504.590
8.300781250000000E-003  4.882812500000000E-004   814.6337
9.277343750000000E-003  4.882812500000000E-004   273.8610
```
When I plot this density map in gnuplot, with the following commands:
```
set palette rgbformulae 34,35,0
set size square
set pm3d map
splot "dens_map.map" u 1:2:(log10($3+10.)) title "Density map"`
```
Which gives me this beautiful image: Now I would like to have the same result with matplotlib.

Response:
Here is my aim at a more complete answer including choosing the color map and a logarithmic normalization of the color axis.
```
import matplotlib.pyplot as plt
import matplotlib.cm as cm
from matplotlib.colors import LogNorm
import numpy as np
x, y, z = np.loadtxt('data.txt', unpack=True)
N = int(len(z)**.5)
z = z.reshape(N, N)
plt.imshow(z+10, extent=(np.amin(x), np.amax(x), np.amin(y), np.amax(y)),
        cmap=cm.hot, norm=LogNorm())
plt.colorbar()
plt.show()
```
I assume here that your data can be transformed into a 2d array by a simple reshape. If this is not the case than you need to work a bit harder on getting the data in this form. Using imshow and not pcolormesh is more efficient here if you data lies on a grid (as it seems to do). The above code snippet results in the following image, that comes pretty close to what you wanted:


Question: How to add a footnote under the x-axis of a plot I couldn't find the right function to add a footnote in my plot. The footnote I want to have is something like an explanation of one item in the legend, but it is too long to put in the legend box. So, I'd like to add a ref number, e.g. [1], to the legend item, and add the footnote in the bottom of the plot, under the x-axis. Which function should I use?

Response:
You would be just use:
```
plt.figtext(0.5, 0.01, "one text and next text", ha="center", fontsize=18, bbox={"facecolor":"orange", "alpha":0.5, "pad":5})
```


Question:
How to remove scientific notation on a matplotlib log-log plot I know that this question has been asked before, but I tried all the possible solutions and none of them worked for me. So, I have a log-log plot in matplotlib, and I would like to avoid scientific notation on the x-axis. This is my code:
```
from numpy import array, log, pi
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
import matplotlib.ticker as mticker

plt.rc('axes.formatter', useoffset=False)

tc = array([7499680.0, 12508380.0, 23858280.0, 34877020.0, 53970660.0, 89248580.0, 161032860.0, 326814160.0, 784460200.0])

theta = array([70, 60, 50, 45, 40, 35, 30, 25, 20])

plt.scatter(theta,tc)

ax=plt.gca()

ax.set_xscale('log')
ax.set_yscale('log')

ax.xaxis.set_major_formatter(mticker.ScalarFormatter())
ax.xaxis.get_major_formatter().set_scientific(False)
ax.xaxis.get_major_formatter().set_useOffset(False)

plt.show()
```
And this is the output: As you can see, the numbers on the x-axis are still in scientific notation. I would like to display them as 20, 30, 40... I tried every possible solution with no result. Thank you very much to everyone that will help. NB. I can't use the plt.loglog() command, because I am doing some curve fitting on the data and I need it like that. NB2. I noticed a very weird thing happening: if I change the code to yaxis.get_mayor_formatter()..., it works on the y-axis! It is just on the x one that it's not working. How is it possible? Edit: maybe it is not clear, but if you look at the code, there are 3 methods that should affect the display of the x-ticks: plt.rc('axes.formatter', useoffset=False), ax.xaxis.set_major_formatter(mticker.ScalarFormatter()) and ax.xaxis.get_major_formatter().set_scientific(False). They are 3 methods that should all do the trick alone, according to what I found around, but they don't. Of course I also tried them one by one and not all together.

Response:
Those are minor ticks on the x-axis (i.e. they are not on integer powers of 10), not major ticks. matplotlib automatically detemines if it should label the major or minor ticks - in this case because you don't have any major ticks displayed in the x range, the minor ticks are being labelled). So, you need to use the set_minor_formatter method:
```
ax.xaxis.set_minor_formatter(mticker.ScalarFormatter())
```
The reason it works on the y-axis is because those ticks are major ticks (i.e. on integer powers of 10), not minor ticks.


Question:
Fitting to Poisson histogram I am trying to fit a curve over the histogram of a Poisson distribution that looks like this I have modified the fit function so that it resembles a Poisson distribution, with the parameter t as a variable. But the curve_fit function can not be plotted and I am not sure why.
```
def histo(bsize):
    N = bsize
    #binwidth
    bw = (dt.max()-dt.min())/(N-1.)
    bin1 = dt.min()+ bw*np.arange(N)
    #define the array to hold the occurrence count
    bincount= np.array([])
    for bin in bin1:
        count = np.where((dt>=bin)&(dt<bin+bw))[0].size
        bincount = np.append(bincount,count)
    #bin center
    binc = bin1+0.5*bw
    plt.figure()
    plt.plot(binc,bincount,drawstyle= 'steps-mid')
    plt.xlabel("Interval[ticks]")
    plt.ylabel("Frequency")
histo(30)
plt.xlim(0,.5e8)
plt.ylim(0,25000)
import numpy as np
from scipy.optimize import curve_fit
delta_t = 1.42e7
def func(x, t):
    return t * np.exp(- delta_t/t)
popt, pcov = curve_fit(func, np.arange(0,.5e8),histo(30))
plt.plot(popt)
```

Response:
The problem with your code is that you do not know what the return values of curve_fit are. It is the parameters for the fit-function and their covariance matrix - not something you can plot directly. Binned Least-Squares Fit In general you can get everything much, much more easily:
```py
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
from scipy.special import factorial
from scipy.stats import poisson

# get poisson deviated random numbers
data = np.random.poisson(2, 1000)

# the bins should be of integer width, because poisson is an integer distribution
bins = np.arange(11) - 0.5
entries, bin_edges, patches = plt.hist(data, bins=bins, density=True, label='Data')

# calculate bin centers
bin_centers = 0.5 * (bin_edges[1:] + bin_edges[:-1])

def fit_function(k, lamb):
    '''poisson function, parameter lamb is the fit parameter'''
    return poisson.pmf(k, lamb)

# fit with curve_fit
parameters, cov_matrix = curve_fit(fit_function, bin_centers, entries)

# plot poisson-deviation with fitted parameter
x_plot = np.arange(0, 15)

plt.plot(
    x_plot,
    fit_function(x_plot, *parameters),
    marker='o', linestyle='',
    label='Fit result',
)
plt.legend()
plt.show()
```
This is the result: Unbinned Maximum-Likelihood fit An even better possibility would be to not use a histogram at all and instead to carry out a maximum-likelihood fit. But by closer examination even this is unnecessary, because the maximum-likelihood estimator for the parameter of the poissonian distribution is the arithmetic mean. However, if you have other, more complicated PDFs, you can use this as example:
```
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import minimize
from scipy.special import factorial
from scipy import stats

def poisson(k, lamb):
    """poisson pdf, parameter lamb is the fit parameter"""
    return (lamb**k/factorial(k)) * np.exp(-lamb)

def negative_log_likelihood(params, data):
    """
    The negative log-Likelihood-Function
    """

    lnl = - np.sum(np.log(poisson(data, params[0])))
    return lnl

def negative_log_likelihood(params, data):
    ''' better alternative using scipy '''
    return -stats.poisson.logpmf(data, params[0]).sum()

# get poisson deviated random numbers
data = np.random.poisson(2, 1000)

# minimize the negative log-Likelihood

result = minimize(negative_log_likelihood,  # function to minimize
                  x0=np.ones(1),            # start value
                  args=(data,),             # additional arguments for function
                  method='Powell',          # minimization method, see docs
                  )
# result is a scipy optimize result object, the fit parameters
# are stored in result.x
print(result)

# plot poisson-distribution with fitted parameter
x_plot = np.arange(0, 15)

plt.plot(
    x_plot,
    stats.poisson.pmf(x_plot, result.x),
    marker='o', linestyle='',
    label='Fit result',
)
plt.legend()
plt.show()
```


Question:
Setting Different error bar colors in bar plot in matplotlib Following Setting Different Bar color in matplotlib Python I would like to change the error bar colors. I have figured out a way after a number of attempts:
```
a = plt.gca()
b = a.bar(range(4), [2]*4, yerr=range(4))
c = a.get_children()[8]
c.set_color(['r','r','b','r'])
```
Is there any better way? Certainly a.get_children()[8] is not a general solution at all.

Response:
If you just want to set them to a single color, use the error_kw kwarg (expected to be a dict of keyword arguments that's passed on to ax.errorbar). Also, just so you know, you can pass a sequence of facecolors directly to bar, though this won't change the errorbar color. As a quick example:
```
import matplotlib.pyplot as plt

fig, ax = plt.subplots()

ax.bar(range(4), [2] * 4, yerr=range(1, 5), alpha=0.5,
       color=['red', 'green', 'blue', 'cyan', 'magenta'],
       error_kw=dict(ecolor='gray', lw=2, capsize=5, capthick=2))
ax.margins(0.05)

plt.show()
```
However, if you want the errorbars to be different colors, you'll either need to plot them individually or modify them afterwards. If you use the latter option, the capline colors actually can't be changed individually (note that they're not changed in @falsetru's example either). For example:
```
import matplotlib.pyplot as plt

fig, ax = plt.subplots()
colors = ['red', 'green', 'blue', 'cyan', 'magenta']

container = ax.bar(range(4), [2] * 4, yerr=range(1, 5), alpha=0.5, color=colors,
       error_kw=dict(lw=2, capsize=5, capthick=2))
ax.margins(0.05)

connector, caplines, (vertical_lines,) = container.errorbar.lines
vertical_lines.set_color(colors)

plt.show()
```
The caplines object in the answer above is a tuple of two Line2Ds: One line for all of the top caps, and one line for all of the bottom caps. There's not way to change the colors of the caps individually (it's easy to set them all to the same color) without removing that artist and creating a LineCollection in its place. Therefore, you're better off just plotting the errorbars individually in this case. E.g.
```
import matplotlib.pyplot as plt

x, height, error = range(4), [2] * 4, range(1,5)
colors = ['red', 'green', 'blue', 'cyan', 'magenta']

fig, ax = plt.subplots()
ax.bar(x, height, alpha=0.5, color=colors)
ax.margins(0.05)

for pos, y, err, color in zip(x, height, error, colors):
    ax.errorbar(pos + 0.4, y, err, lw=2, capsize=5, capthick=2, color=color)

plt.show()
```


Question: Plotting only upper/lower triangle of a heatmap In maptplotlib, one can create a heatmap representation of a correlation matrix using the imshow function. By definition, such a matrix is symmetrical around its main diagonal, therefore there is no need to present both the upper and lower triangles. For example: (source: wisc.edu) The above example was taken from this site Unfortunately, I couldn't figure out how to do this in matplotlib. Setting upper/lower part of the matrix to None results in black triangle. I have googled for "matplotlib missing values", but couldn't find anything helpful

Response:
The problem with the answer provided by doug is that it relies on the fact that the colormap maps zero values to white. This means that colormaps that do not include white color are not useful. The key for solution is cm.set_bad function. You mask the unneeded parts of the matrix with None or with NumPy masked arrays and set_bad to white, instead of the default black. Adopting doug's example we get the following:
```
import numpy as NP
from matplotlib import pyplot as PLT
from matplotlib import cm as CM

A = NP.random.randint(10, 100, 100).reshape(10, 10)
mask =  NP.tri(A.shape[0], k=-1)
A = NP.ma.array(A, mask=mask) # mask out the lower triangle
fig = PLT.figure()
ax1 = fig.add_subplot(111)
cmap = CM.get_cmap('jet', 10) # jet doesn't have white color
cmap.set_bad('w') # default value is 'k'
ax1.imshow(A, interpolation="nearest", cmap=cmap)
ax1.grid(True)
PLT.show()
```


Question: What are the hex codes of matplotlib tab10 palette? Do you know what are the hex codes or RGB values of the "tab" palette (the default 10 colors: tab:blue, tab:orange, etc...) of matplotlib ? And possibly do you know how if there's a way to obtain the hex code for any named color in matplotlib ?

Response:
Turns out this piece of code from the matplotlib examples gave me the answer I was after. The hex codes of the "tableau" palette are as follows:
```
tab:blue : #1f77b4
tab:orange : #ff7f0e
tab:green : #2ca02c
tab:red : #d62728
tab:purple : #9467bd
tab:brown : #8c564b
tab:pink : #e377c2
tab:gray : #7f7f7f
tab:olive : #bcbd22
tab:cyan : #17becf
```
Using the following code I made a dictionnary containing all the named colors and their respective hex code :
```
import matplotlib.colors as mcolors

mcolors.TABLEAU_COLORS
mcolors.XKCD_COLORS
mcolors.CSS4_COLORS
#Base colors are in RGB so they need to be converted to HEX
BASE_COLORS_hex = {name:mcolors.rgb2hex(color) for name,color in mcolors.BASE_COLORS.items()}

all_named_colors = {}
all_named_colors.update(mcolors.TABLEAU_COLORS)
all_named_colors.update(BASE_COLORS_hex)
all_named_colors.update(mcolors.CSS4_COLORS)
all_named_colors.update(mcolors.XKCD_COLORS)

#print(all_named_colors)
print(all_named_colors["tab:blue"])

```python
#1f77b4
#Output
#```
```


Question:
How to surface plot/3d plot from dataframe I am new to pandas and matplotlib. I couldn't get the exact reference to plot my DataFrame which has the following schema:
```
schema = StructType([
StructField("x", IntegerType(), True),
StructField("y", IntegerType(), True),
StructField("z", IntegerType(), True)])
```
I'd like to plot 3d graph w.r.t. x, y and z. Here is the sample code I used:
```
import matplotlib.pyplot as pltt

dfSpark = sqlContext.createDataFrame(tupleRangeRDD, schema) // reading as spark df
df = dfSpark.toPandas()
fig = pltt.figure();
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(df['x'], df['y'], df['z'])
```
I am getting a empty graph plot. I'm definitely missing something. Any pointers? Request-1: Print df
```
def print_full(x):
    pd.set_option('display.max_rows', len(x))
    print(x)
    pd.reset_option('display.max_rows')

print_full(df)
```
Result of top 10:
```
x    y       z
0      301  301      10
1      300  301      16
2      300  300       6
3      299  301      30
4      299  300      20
5      299  299      14
6      298  301      40
7      298  300      30
8      298  299      24
9      298  298      10
10     297  301      48
```

Response:
.plot_surface() takes 2D arrays as inputs, not 1D DataFrame columns. This has been explained quite well here, along with the below code that illustrates how one could arrive at the required format using DataFrame input. Reproduced below with minor modifications like additional comments. Alternatively, however, there is .plot_trisurf() which uses 1D inputs. I've added an example in the middle of the code.
```
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib.ticker import LinearLocator, FormatStrFormatter
from mpl_toolkits.mplot3d import Axes3D

## Matplotlib Sample Code using 2D arrays via meshgrid
X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X ** 2 + Y ** 2)
Z = np.sin(R)
fig = plt.figure()
ax = Axes3D(fig)
surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm,
                       linewidth=0, antialiased=False)
ax.set_zlim(-1.01, 1.01)

ax.zaxis.set_major_locator(LinearLocator(10))
ax.zaxis.set_major_formatter(FormatStrFormatter('%.02f'))

fig.colorbar(surf, shrink=0.5, aspect=5)
plt.title('Original Code')
plt.show()
```
```
## DataFrame from 2D-arrays
x = X.reshape(1600)
y = Y.reshape(1600)
z = Z.reshape(1600)
df = pd.DataFrame({'x': x, 'y': y, 'z': z}, index=range(len(x)))

# Plot using `.trisurf()`:

ax.plot_trisurf(df.x, df.y, df.z, cmap=cm.jet, linewidth=0.2)
plt.show()
```
```
# 2D-arrays from DataFrame
x1 = np.linspace(df['x'].min(), df['x'].max(), len(df['x'].unique()))
y1 = np.linspace(df['y'].min(), df['y'].max(), len(df['y'].unique()))

"""
x, y via meshgrid for vectorized evaluation of
2 scalar/vector fields over 2-D grids, given
one-dimensional coordinate arrays x1, x2,..., xn.
"""

x2, y2 = np.meshgrid(x1, y1)

# Interpolate unstructured D-dimensional data.
z2 = griddata((df['x'], df['y']), df['z'], (x2, y2), method='cubic')

# Ready to plot
fig = plt.figure()
ax = fig.gca(projection='3d')
surf = ax.plot_surface(x2, y2, z2, rstride=1, cstride=1, cmap=cm.coolwarm,
                       linewidth=0, antialiased=False)
ax.set_zlim(-1.01, 1.01)

ax.zaxis.set_major_locator(LinearLocator(10))
ax.zaxis.set_major_formatter(FormatStrFormatter('%.02f'))

fig.colorbar(surf, shrink=0.5, aspect=5)
plt.title('Meshgrid Created from 3 1D Arrays')

plt.show()
```


Question: Plotting probability density function by sample with matplotlib [closed] It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center. Closed 12 years ago. I want to plot an approximation of probability density function based on a sample that I have; The curve that mimics the histogram behaviour. I can have samples as big as I want.

Response:
If you want to plot a distribution, and you know it, define it as a function, and plot it as so:
```
import numpy as np
from matplotlib import pyplot as plt

def my_dist(x):
    return np.exp(-x ** 2)

x = np.arange(-100, 100)
p = my_dist(x)
plt.plot(x, p)
plt.show()
```
If you don't have the exact distribution as an analytical function, perhaps you can generate a large sample, take a histogram and somehow smooth the data:
```
import numpy as np
from scipy.interpolate import UnivariateSpline
from matplotlib import pyplot as plt

N = 1000
n = N//10
s = np.random.normal(size=N)   # generate your data sample with N elements
p, x = np.histogram(s, bins=n) # bin it into n = N//10 bins
x = x[:-1] + (x[1] - x[0])/2   # convert bin edges to centers
f = UnivariateSpline(x, p, s=n)
plt.plot(x, f(x))
plt.show()
```
You can increase or decrease s (smoothing factor) within the UnivariateSpline function call to increase or decrease smoothing. For example, using the two you get:


Question:
Python matplotlib - setting x-axis scale I have this graph displaying the following:
```
plt.plot(valueX, scoreList)
plt.xlabel("Score number") # Text for X-Axis
plt.ylabel("Score") # Text for Y-Axis
plt.title("Scores for the topic "+progressDisplay.topicName)
plt.show()
```
valueX = [1, 2, 3, 4] and scoreList = [5, 0, 0, 2] I want the scale to go up in 1's, no matter what values are in 'scoreList'. Currently get my x-axis going up in .5 instead of 1s. How do I set it so it goes up only in 1?

Response:
Just set the xticks yourself.
```
plt.xticks([1,2,3,4])
```
or
```
plt.xticks(valueX)
```
Since the range functions happens to work with integers you could use that instead:
```
plt.xticks(range(1, 5))
```
Or be even more dynamic and calculate it from the data:
```
plt.xticks(range(min(valueX), max(valueX)+1))
```


Question: Setting plot background colour in Seaborn I am using Seaborn to plot some data in Pandas. I am making some very large plots (factorplots). To see them, I am using some visualisation facilities at my university. I am using a Compound screen made up of 4 by 4 monitors with small (but nonzero) bevel -- the gap between the screens. This gap is black. To minimise the disconnect between the screen i want the graph backgound to be black. I have been digging around the documentation and playing around and I can't work it out.. Surely this is simple. I can get grey background using set_style('darkgrid') do i need to access the plot in matplotlib directly?

Response:
seaborn.set takes an rc argument that accepts a dictionary of valid matplotlib rcparams. So we need to set two things: the axes.facecolor, which is the color of the area where the data are drawn, and the figure.facecolor, which is the everything a part of the figure outside of the axes object. (edited with advice from @mwaskom) So if you do:
```
%matplotlib inline
import matplotlib.pyplot as plt
import seaborn
seaborn.set(rc={'axes.facecolor':'cornflowerblue', 'figure.facecolor':'cornflowerblue'})

fig, ax = plt.subplots()
```
You get: And that'll work with your FacetGrid as well.


Question:
Plotting Pandas Multiindex Bar Chart How can I plot a Python Pandas multiindex dataframe as a bar chart with group labels? Do any of the plotting libraries directly support this? This SO post shows a custom solution using matplotlib, but is there direct support for it? As an example:
```
quarter  company
Q1       Blue       100
         Green      300
Q2       Blue       200
         Green      350
Q3       Blue       300
         Green      400
Q4       Blue       400
         Green      450
Name: count, dtype: int64
```
...can this dataframe be plotted with group labels like this?

Response:
```
import pandas as pd

data = pd.DataFrame([
        ('Q1','Blue',100),
        ('Q1','Green',300),
        ('Q2','Blue',200),
        ('Q2','Green',350),
        ('Q3','Blue',300),
        ('Q3','Green',400),
        ('Q4','Blue',400),
        ('Q4','Green',450),
    ],
    columns=['quarter', 'company', 'value']
)
data = data.set_index(['quarter', 'company']).value

data.unstack().plot(kind='bar', stacked=True)
```
If you don't want to stack your bar chart:
```
data.unstack().plot(kind='bar')
```


Question:
AttributeError: Unknown property axisbg Here is a code am trying to run:
```
ax = plt.axes(axisbg='#E6E6E6')
ax.set_axisbelow(True)
plt.grid(color='w',linestyle='solid')

for spine in ax.spines.values():
   spine.set_visible(False)

ax.xaxis.tick_bottom()
ax.yaxis.tick_left()

ax.tick_params(colors='gray',direction='out')
for tick in ax.get_xticklabels():
   tick.set_color('gray')
for tick in ax.get_yaxislabels():
   tick.set_color('gray')

ax.hist(x,edgecolor='E6E6E6',color='E6E6E6');
```
And the Error is: AttributeError: Unknown property axisbg Please help me identify the error.

Response:
Replace the below line of code
```
ax = plt.axes(axisbg='#E6E6E6')
```
with
```
ax = plt.axes(facecolor='#E6E6E6')
```


Question:
Getting information for bins from the histogram function I am plotting a histogram in python using matplotlib by:
```py
plt.hist(nparray, bins=10, label='hist')
```
Is it possible to print a dataframe that has the information for all the bins, like number of elements in every bin?

Response:
The return values of plt.hist are: Returns: tuple : (n, bins, patches) or ([n0, n1, ...], bins, [patches0, patches1,...]) So all you need to do is capture the return values appropriately. For example:
```
import numpy as np
import matplotlib.pyplot as plt

# generate some uniformly distributed data
x = np.random.rand(1000)

# create the histogram
(n, bins, patches) = plt.hist(x, bins=10, label='hst')

plt.show()

# inspect the counts in each bin

```python
print n
[102  87 102  83 106 100 104 110 102 104]

# and we see that the bins are approximately uniformly filled.
# create a second histogram with more bins (but same input data)
(n2, bins2, patches) = plt.hist(x, bins=20, label='hst')
```

```python
print n2
[54 48 39 48 51 51 37 46 49 57 50 50 52 52 59 51 58 44 58 46]

# bins are uniformly filled but obviously with fewer in each bin.
```
The bins that is returned defines the edges of each bin that was used.
```


Question:
plot data from CSV file with matplotlib I have a CSV file at e:\dir1\datafile.csv. It contains three columns and 10 heading and trailing lines need to be skipped. I would like to plot it with numpy.loadtxt(), for which I haven't found any rigorous documentation. Here is what I started to write from the several tries I found on the web.
```
import matplotlib as mpl
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cbook as cbook

def read_datafile(file_name):
    # the skiprows keyword is for heading, but I don't know if trailing lines
    # can be specified
    data = np.loadtxt(file_name, delimiter=',', skiprows=10)
    return data

data = read_datafile('e:\dir1\datafile.csv')

x = ???
y = ???

fig = plt.figure()

ax1 = fig.add_subplot(111)

ax1.set_title("Mains power stability")
ax1.set_xlabel('time')
ax1.set_ylabel('Mains voltage')

ax1.plot(x,y, c='r', label='the data')

leg = ax1.legend()

plt.show()
```

Response:
According to the docs numpy.loadtxt is a fast reader for simply formatted files. The genfromtxt function provides more sophisticated handling of, e.g., lines with missing values. so there are only a few options to handle more complicated files. As mentioned numpy.genfromtxt has more options. So as an example you could use
```
import numpy as np
data = np.genfromtxt('e:\dir1\datafile.csv', delimiter=',', skip_header=10,
                     skip_footer=10, names=['x', 'y', 'z'])
```
to read the data and assign names to the columns (or read a header line from the file with names=True) and than plot it with
```
ax1.plot(data['x'], data['y'], color='r', label='the data')
```
I think numpy is quite well documented now. You can easily inspect the docstrings from within ipython or by using an IDE like spider if you prefer to read them rendered as HTML.


Question:
Set zlim in matplotlib scatter3d I have three lists xs, ys, zs of data points in Python and I am trying to create a 3d plot with matplotlib using the scatter3d method.
```
import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
plt.xlim(290)
plt.ylim(301)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.scatter(xs, ys, zs)
plt.savefig('dateiname.png')
plt.close()
```
The plt.xlim() and plt.ylim() work fine, but I don't find a function to set the borders in z-direction. How can I do so?

Response:
Simply use the set_zlim function of the axes object (like you already did with set_zlabel, which also isn't available as plt.zlabel):
```
import matplotlib.pyplot as plt
import numpy as np

xs = np.random.random(10)
ys = np.random.random(10)
zs = np.random.random(10)

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.scatter(xs, ys, zs)
ax.set_zlim(-10, 10)
```


Question:
Plotting grids across the subplots Python matplotlib I have tried the following:
```
d = [1,2,3,4,5,6,7,8,9]
f = [0,1,0,0,1,0,1,1,0]
fig = plt.figure()
fig.set_size_inches(30,10)
ax1 = fig.add_subplot(211)
line1 = ax1.plot(d,marker='.',color='b',label="1 row")
ax2 = fig.add_subplot(212)
line1 = ax2.plot(f,marker='.',color='b',label="1 row")
ax1.grid()
ax2.grid()
plt.show()
```
I got the following output : But I was expecting the following output: How I can get the grids across the two plots?

Response:
There is no built-in option to create inter-subplot grids. In this case I'd say an easy option is to create a third axes in the background with the same grid in x direction, such that the gridline can be seen in between the two subplots.
```
import matplotlib.pyplot as plt

d = [1,2,3,4,5,6,7,8,9]
f = [0,1,0,0,1,0,1,1,0]

fig, (ax1,ax2) = plt.subplots(nrows=2, sharex=True)
ax3 = fig.add_subplot(111, zorder=-1)
for _, spine in ax3.spines.items():
    spine.set_visible(False)
ax3.tick_params(labelleft=False, labelbottom=False, left=False, right=False )
ax3.get_shared_x_axes().join(ax3,ax1)
ax3.grid(axis="x")

line1 = ax1.plot(d, marker='.', color='b', label="1 row")
line1 = ax2.plot(f, marker='.', color='b', label="1 row")
ax1.grid()
ax2.grid()
plt.show()
```


Question:
Matplotlib: Don't show errorbars in legend I'm plotting a series of data points with x and y error but do NOT want the errorbars to be included in the legend (only the marker). Is there a way to do so? Example:
```
import matplotlib.pyplot as plt
import numpy as np
subs=['one','two','three']
x=[1,2,3]
y=[1,2,3]
yerr=[2,3,1]
xerr=[0.5,1,1]
fig,(ax1)=plt.subplots(1,1)
for i in np.arange(len(x)):
    ax1.errorbar(x[i],y[i],yerr=yerr[i],xerr=xerr[i],label=subs[i],ecolor='black',marker='o',ls='')
ax1.legend(loc='upper left', numpoints=1)
fig.savefig('test.pdf', bbox_inches=0)
```

Response:
You can modify the legend handler. See the legend guide of matplotlib. Adapting your example, this could read:
```
import matplotlib.pyplot as plt
import numpy as np

subs=['one','two','three']
x=[1,2,3]
y=[1,2,3]
yerr=[2,3,1]
xerr=[0.5,1,1]
fig,(ax1)=plt.subplots(1,1)

for i in np.arange(len(x)):
    ax1.errorbar(x[i],y[i],yerr=yerr[i],xerr=xerr[i],label=subs[i],ecolor='black',marker='o',ls='')

# get handles
handles, labels = ax1.get_legend_handles_labels()
# remove the errorbars
handles = [h[0] for h in handles]
# use them in the legend
ax1.legend(handles, labels, loc='upper left',numpoints=1)

plt.show()
```
This produces


Question: Is there a way of drawing a caption box in matplotlib Is there a function for drawing a caption box underneath a figure/graph using matplotlib? I have searched google and haven't found any such function. something like what is shown in the image would be great.

Response:
Use pyplot.text. Here is some sample code:
```
from matplotlib import pyplot as plt
import numpy as np

x = np.arange(0,3,.25)
y = np.sin(x)
txt = '''
    Lorem ipsum dolor sit amet, consectetur adipisicing elit,
    sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
    Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
    nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
    reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
    pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
    culpa qui officia deserunt mollit anim id est laborum.'''

fig = plt.figure()
ax1 = fig.add_axes((.1,.4,.8,.5))
ax1.bar(x,y,.2)
fig.text(.1,.1,txt)
plt.show()
```
It produces this: If you want automatic word-wrapping, have a look at this post. I'm not sure I can help you get it full-justified.


Question:
Draw axis lines or the origin for Matplotlib contour plot I want to draw x=0 and y=0 axis in my contour plot, using a white color. If that is too cumbersome, I would like to have a white dot denoting where the origin is. My contour plot looks as follows and the code to create it is given below.
```
xvec = linspace(-5.,5.,100)
X,Y = meshgrid(xvec, xvec)
fig = plt.figure(figsize=(6, 4))
contourf(X, Y, W,100)
plt.colorbar()
```

Response:
There are a number of options (E.g. centered spines), but in your case, it's probably simplest to just use axhline and axvline. E.g.
```
import numpy as np
import matplotlib.pyplot as plt

xvec = np.linspace(-5.,5.,100)
x,y = np.meshgrid(xvec, xvec)
z = -np.hypot(x, y)

plt.contourf(x, y, z, 100)
plt.colorbar()

plt.axhline(0, color='white')
plt.axvline(0, color='white')

plt.show()
```


Question:
use matplotlib color map for color cycle If I create colors by e.g:
```
import numpy as np
from matplotlib import pyplot as plt

n = 6
color = plt.cm.coolwarm(np.linspace(0.1,0.9,n))
color
```
color is a numpy array:
```
array([[ 0.34832334,  0.46571115,  0.88834616,  1.        ],
       [ 0.56518158,  0.69943844,  0.99663507,  1.        ],
       [ 0.77737753,  0.84092121,  0.9461493 ,  1.        ],
       [ 0.93577377,  0.8122367 ,  0.74715647,  1.        ],
       [ 0.96049006,  0.61627642,  0.4954666 ,  1.        ],
       [ 0.83936494,  0.32185622,  0.26492398,  1.        ]])
```
However, If I plug in the RGB values (without the alpha value 1) as tuples in my .mplstyle file (map(tuple,color[:,0:-1])), I get an error similar to this one:
```
in file "/home/moritz/.config/matplotlib/stylelib/ggplot.mplstyle"
    Key axes.color_cycle: [(0.34832334141176474 does not look like a color arg
  (val, error_details, msg))
```
Any ideas why?

Response:
"Continuous" colormap If you want to cycle through N colors from a "continous" colormap, like e.g. the default viridis map, the solution by @Gerges works nicely.
```
import matplotlib.pyplot as plt

N = 6
plt.rcParams["axes.prop_cycle"] = plt.cycler("color", plt.cm.viridis(np.linspace(0,1,N)))

fig, ax = plt.subplots()
for i in range(N):
    ax.plot([0,1], [i, 2*i])

plt.show()
```
"Discrete" colormap Matplotlib provides a few colormap that are "discrete" in the sense that they hold some low number of distinct colors for qualitative visuals, like the tab10 colormap. To cycle through such colormap, the solution might be to not use N but just port all colors of the map to the cycler.
```
import matplotlib.pyplot as plt

plt.rcParams["axes.prop_cycle"] = plt.cycler("color", plt.cm.tab20c.colors)

fig, ax = plt.subplots()
for i in range(15):
    ax.plot([0,1], [i, 2*i])

plt.show()
```
Note that only ListedColormaps have the .colors attribute, so this only works for those colormap, but not e.g. the jet map. Combined solution The following is a general purpose function that takes a colormap as input and outputs a corresponding cycler. I originally proposed this solution in this matplotlib issue.
```
from matplotlib.pyplot import cycler
import numpy as np
from matplotlib.colors import LinearSegmentedColormap, ListedColormap
import matplotlib.cm

def get_cycle(cmap, N=None, use_index="auto"):
    if isinstance(cmap, str):
        if use_index == "auto":
            if cmap in ['Pastel1', 'Pastel2', 'Paired', 'Accent',
                        'Dark2', 'Set1', 'Set2', 'Set3',
                        'tab10', 'tab20', 'tab20b', 'tab20c']:
                use_index=True
            else:
                use_index=False
        cmap = matplotlib.cm.get_cmap(cmap)
    if not N:
        N = cmap.N
    if use_index=="auto":
        if cmap.N > 100:
            use_index=False
        elif isinstance(cmap, LinearSegmentedColormap):
            use_index=False
        elif isinstance(cmap, ListedColormap):
            use_index=True
    if use_index:
        ind = np.arange(int(N)) % cmap.N
        return cycler("color",cmap(ind))
    else:
        colors = cmap(np.linspace(0,1,N))
        return cycler("color",colors)
```
Usage for the "continuous" case:
```
import matplotlib.pyplot as plt
N = 6
plt.rcParams["axes.prop_cycle"] = get_cycle("viridis", N)

fig, ax = plt.subplots()
for i in range(N):
    ax.plot([0,1], [i, 2*i])

plt.show()
```
Usage for the "discrete" case
```
import matplotlib.pyplot as plt

plt.rcParams["axes.prop_cycle"] = get_cycle("tab20c")

fig, ax = plt.subplots()
for i in range(15):
    ax.plot([0,1], [i, 2*i])

plt.show()
```


Question: Placement of text e.g. suptitle inside the frame So far i have placed my suptitles above the frame, like this: How can i get the suptitles from above the frame into the frame? So far i have a solution that just prints a text and sets it on the right position with computing xlim and ylim. However this is errorprone and if the text is different it just looks aweful. Is there a way to set the suplabel into the frame? Or just place text below the frame and centered? it would be really convenient, if i did not need to know about the data that is displayed inside the frame.

Response:
Your solution using text is also my go-to solution. However, you don't need to compute the position based on xlim and ylim. If you set transform=ax.transAxes the coordinates for positioning the text are taken as being relative to the axes bounding box (0,0 being the lower left corner). Like so:
```
data = range(1,10);
fig = figure()
for i in range(6):
    ax = fig.add_subplot(2,3,i)

    ax.text(.5,.9,'centered title',
        horizontalalignment='center',
        transform=ax.transAxes)

    ax.plot(data)
show()
```
Hope that helps!


Question:
How do you just show the text label in plot legend? (e.g. remove a label's line in the legend) I want to show the text for a line's label in the legend, but not a line too (As shown in the figure below): I have tried to minimise the legend's line and label, and overwrite only the new-label too (as in the code below). However, the legend brings both back.
```
legend = ax.legend(loc=0, shadow=False)
    for label in legend.get_lines():
        label.set_linewidth(0.0)
    for label in legend.get_texts():
        label.set_fontsize(0)

    ax.legend(loc=0, title='New Title')
```

Response:
At that point, it's arguably easier to just use annotate. For example:
```
import numpy as np
import matplotlib.pyplot as plt

data = np.random.normal(0, 1, 1000).cumsum()

fig, ax = plt.subplots()
ax.plot(data)
ax.annotate('Label', xy=(-12, -12), xycoords='axes points',
            size=14, ha='right', va='top',
            bbox=dict(boxstyle='round', fc='w'))
plt.show()
```
However, if you did want to use legend, here's how you'd do it. You'll need to explicitly hide the legend handles in addition to setting their size to 0 and removing their padding.
```
import numpy as np
import matplotlib.pyplot as plt

data = np.random.normal(0, 1, 1000).cumsum()

fig, ax = plt.subplots()
ax.plot(data, label='Label')

leg = ax.legend(handlelength=0, handletextpad=0, fancybox=True)
for item in leg.legendHandles:
    item.set_visible(False)
plt.show()
```


Question:
Latex on python: \alpha and \beta don't work? I'm using matplotlib to produce some graphics, and I'm using latex for the legends. More specifically, I'm trying to use something like this:
```
loglog(x,x, '-r',label='$ \alpha $')
legend()
show()
```
However, this code does not present a legend on the figure, and gets error after I close the image. I'm using the enthought package (for mac), but the error comes from the pylab/scipy. The error the appears is exactly:
```
$ lpha $ (at char 0), (line:1, col:1)
```
However, if use the \mu or \gamma, it works well!! I only found about this problem on \beta and \alpha. Does anyone knows what this can be? I believe python is interpreting "\a" as some character... but I don't know how should I debug / avoid it.

Response:
The issue is that \a and \b have special meaning inside a Python string literal. I recommend that you use raw strings whenever there is a backslash embedded inside a string:
```
r'$ \alpha $'
```


Question:
How to change font properties of a matplotlib colorbar label? In matplotlib, I want to change the font properties for a colorbar label. For example I want the label to appear bold. Here is some example code:
```
from matplotlib.pylab import *
pcolor(arange(20).reshape(4,5))
cb = colorbar(label='a label')
```
and the result, where I want "a label" to appear bold: All other answers on this site only answer how to change ticklabels or change all fonts in general (via modification of the matplotlibrc file)

Response:
This two-liner can be used with any Text property (http://matplotlib.org/api/text_api.html#matplotlib.text.Text)
```
cb = plt.colorbar()
cb.set_label(label='a label',weight='bold')
```


Question:
Linewidth is added to the length of a line When I draw a line segment in matplotlib the linewidth seems to be added to the length of the line. Below my code (not the most pythonic code, but it should do the trick). Am I doing something wrong or is this just a feature of matplotlib?
```python
import matplotlib.pyplot as plt
import numpy as np

L1 = 100
L2 = 75
L3 = 100
Y = 3
N = 5
l_prev = 0
for l, c in zip(np.linspace(0, L1, N), range(N)):
    plt.plot([l_prev, l], [0, 0], 'r', linewidth=20)
    l_prev = l
l_prev = L1
for l, c in zip(np.linspace(L1, L1 + L2, N), range(N)):
    plt.plot([l_prev, l], [Y, Y], 'g', linewidth=1)
    l_prev = l
l_prev = L1
for l, c in zip(np.linspace(L1, L1 + L3, N), range(N)):
    p = plt.plot([l_prev, l], [-Y, -Y], 'b', linewidth=10)
    l_prev = l
plt.axvspan(xmin=L1, xmax=L1)
plt.axis([-5, 205, -5, 5])
plt.show()
```
What I expected to see is three line segments: [0,L1], [L1,L2] and [L1,L3]. But the first line [0,L1] extends to L1 + 'the diameter'....

Response:
It looks like the default solid_capstyle is projecting, which isn't the one you want:
```
plt.figure()
plt.plot([0, 100], [5, 5], linewidth=50, linestyle="-", c="blue",
         solid_capstyle="butt")
plt.plot([0, 100], [15, 15], linewidth=50, linestyle="-", c="red",
         solid_capstyle="round")
plt.plot([0, 100], [25, 25], linewidth=50, linestyle="-", c="purple",
         solid_capstyle="projecting")
plt.axvline(x=100, c="black")
plt.xlim(0, 125)
plt.ylim(0, 30)
plt.savefig("cap.png")
```


Question:
White lines in matplotlib's pcolor In some pdf viewers such as Preview on OSX, plots made with matplotlib's pcolor have white lines (see image below). How can I get rid of them? The source code is very simple (choose any data for x,y,z):
```
import matplotlib
matplotlib.use("pdf")
import matplotlib.pyplot as pl
pl.figure()
pl.pcolormesh(x,y,z,cmap="Blues",linewidth=0)
pl.savefig("heatmap.pdf")
```

Response:
The comments have a good solution that utilizes imshow. When imshow is not appropriate for the input data (e.g. it is not uniformly spaced) this generally solves this problem,
```
pcol = pl.pcolormesh(x,y,z,cmap="Blues",linewidth=0,)
pcol.set_edgecolor('face')
```
If that approach does not reduce the lines sufficiently, you can also try this:
```
pl.pcolormesh(x,y,z,cmap="Blues",linewidth=0,rasterized=True)
```
In addition to reducing the lines between squares this approach also tends to reduce file size a bit, which is sometimes useful. In this case you may want to tune the dpi setting when saving (e.g. pl.savefig("heatmap.pdf", dpi=300)) until you get something that is satisfactory.


Question:
How to write annotation outside the drawing in data coords My graphic goes from y=-1 to y=10 I want to write a small piece of text in an arbitrary position, say at x=2000, y=5:
```
ax.annotate('MgII', xy=(2000.0, 5.0),  xycoords='data')
```
Now I want the same, but this time the piece of text must be outside the graphic, but in the exact position I mark in data coordinates:
```
ax.annotate('MgII', xy=(2000.0, 10.5),  xycoords='data')
```
But it then disappears (remember my graphic goes from -1 to 10). There is plenty of space free on top of the graphic. And, if I specify
```
xy=(2000.0, 9.999)
```
then the label appears nearly where I want it, only it is too close to the top border of the picture. I want it at y=10.5, specifically.

Response:
```
ax.annotate('MgII', xy=(2000.0, 10.5), xycoords='data', annotation_clip=False)
```
By default in data units the annotation is only drawn if it is in axes. You might be better off using a blended transform:
```
trans = ax.get_xaxis_transform() # x in data untis, y in axes fraction
 ann = ax.annotate('MgII', xy=(2000, 1.05 ), xycoords=trans)
```


Question:
Matplotlib with annotation cut off from the saved figure I'm using matplotlib to draw something figure while using annotations. The problem I experienced is that the annotation (which is outside the plotting area) is cut off from the saved picture, as shown in the following figure. This following figure is the one I want: Anybody knows how to solve this problem? I noticed people suggest using plt.tight_plot() or fig.autolayout in rcParams, but that doesn't seem to work. Below is the code for producing the figure.
```
fig, ax = plt.subplots()
ax.set_xlim([-0.02,1.1])
ax.set_ylim([-0.02,1.1])

ax.plot([0,0,0,0.5,0.5,0.5,1,1,1], [0,0.5,1,0,0.5,1,0,0.5,1], 'go')

ax.annotate("Digit 2",
            xy=(0.5, -0.1), xycoords='data',
            xytext=(0.5, -0.3), textcoords='data',
            arrowprops=dict(arrowstyle="->",
                            connectionstyle="arc3"),
             annotation_clip=False,
             fontsize = 12,
             ha='center',
            )

ax.annotate("Level 2",
            xy=(-0.1, 1), xycoords='data',
            xytext=(-0.35, 1), textcoords='data',
            arrowprops=dict(arrowstyle="->",
                            connectionstyle="arc3"),
                    annotation_clip=False,
                    fontsize = 12,
                    va='center',
            )

plt.savefig('sample.png', dpi = 300)
```

Response:
Save figure with the bbox_inches argument
```
plt.savefig('sample.png', bbox_inches="tight")
```


Question:
Adding a legend to a matplotlib boxplot with multiple plots on same axes I have a boxplot generated with matplotlib: However, I have no idea how to generate the legend. I get a warning saying: Legend does not support handles for dict instances. or No artists with labels found to put in legend. I've done a fair bit of searching and there doesn't seem to be an example showing how to achieve this.
```
bp1 = ax.boxplot(data1, positions=[1,4], notch=True, widths=0.35, patch_artist=True)
bp2 = ax.boxplot(data2, positions=[2,5], notch=True, widths=0.35, patch_artist=True)

ax.legend([bp1, bp2], ['A', 'B'], loc='upper right')
```

Response:
The boxplot returns a dictionary of artists result : dict A dictionary mapping each component of the boxplot to a list of the matplotlib.lines.Line2D instances created. That dictionary has the following keys (assuming vertical boxplots): boxes: the main body of the boxplot showing the quartiles and the median’s confidence intervals if enabled. [...] Using the boxes, you can get the legend artists as
```
ax.legend([bp1["boxes"][0], bp2["boxes"][0]], ['A', 'B'], loc='upper right')
```
Complete example:
```
import matplotlib.pyplot as plt
import numpy as np; np.random.seed(1)

data1=np.random.randn(40,2)
data2=np.random.randn(30,2)

fig, ax = plt.subplots()
bp1 = ax.boxplot(data1, positions=[1,4], notch=True, widths=0.35,
                 patch_artist=True, boxprops=dict(facecolor="C0"))
bp2 = ax.boxplot(data2, positions=[2,5], notch=True, widths=0.35,
                 patch_artist=True, boxprops=dict(facecolor="C2"))

ax.legend([bp1["boxes"][0], bp2["boxes"][0]], ['A', 'B'], loc='upper right')

ax.set_xlim(0,6)
plt.show()
```


Question:
ConversionError: Failed to convert value(s) to axis units I have a dataframe dd containing 84 rows and 3 columns. Now I want to plot an Area Plot with it, and use its index as xticks, so I do the following:
```py
dd.plot(kind='area')
plt.show()
```
But I got this result: It turns out that some xticks are hidden automatically: there should be 84 xticks, but only 9 of them are shown (seems to be hidden automatically). I found a similar question here, but when I tried the method mentioned in the link, I got an CnoversionError:
```py
ConversionError: Failed to convert value(s) to axis units: Index(['!', '"', '#', '$', '%', '&', ''', '(', ')', '*', '+', ',', '-', '.',
       '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<',
       '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
       'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
       'Y', 'Z', '[', '\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f',
       'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't'],
      dtype='object')
```
I noticed that the difference between my question and the link above is that the index of my DataFrame has a dtype object (they are string), and I found that if I change the index to a list of int, the error does go away. The code to reproduce the Error:
```py
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

dd=pd.DataFrame(np.random.rand(84,3),index=[chr(ascii) for ascii in range(33,33+84)])

dd.plot(kind='area',xticks=dd.index)

plt.show()
```

Response:
We need to provide index positions of the labels in the xticks function, labels order should be as per the index positions. xticks function takes 3 arguments, ticks should be position of indexes of the labels labels argument takes the list of label values rotation takes how the label should be presented in the plot
```py
x = df['state']
y = df['sales']
tickvalues = range(0,len(x)) // or tickvalues = df.index
plt.figure(figsize = (20,5))
plt.xticks(ticks = tickvalues ,labels = labellist, rotation = 'vertical')
plt.plot(x,y)
```