Question:
bbox_to_anchor and loc in matplotlib I came across matplotlib code which customizes legend location using keywords loc and bbox_to_anchor. For example :
```
fig.legend([line1, line2], ['series1', 'series2'], bbox_to_anchor=[0.5, 0.5],
           loc='center', ncol=2)
```
I have seen variation of above where bbox_to_anchor is used after loc. I understand the purpose of using bbox_to_anchor and loc separately. However, is there any benefit of using both in the same legend specification? From my understanding and usage, it appears to me that if bbox_to_anchor is specified, then the loc parameter is pretty much don't care. Can anyone confirm this? I don't see any documentation regarding this.

Response:
When bbox_to_anchor and loc are used together, the loc argument will inform matplotlib which part of the bounding box of the legend should be placed at the arguments of bbox_to_anchor. For example (I've simplified the command a bit), the three options below will produce different locations for your legend,
```
fig.legend([line1], ['series1'], bbox_to_anchor=[0.5, 0.5], loc='center')
 fig.legend([line1], ['series1'], bbox_to_anchor=[0.5, 0.5], loc='center left')
 fig.legend([line1], ['series1'], bbox_to_anchor=[0.5, 0.5], loc='center right')
```
The first command will put the center of the bounding box at axes coordinates 0.5,0.5. The second will put the center left edge of the bounding box at the same coordinates (i.e. shift the legend to the right). Finally, the third option will put the center right edge of the bounding box at the coordinates (i.e. shift the legend to the left).


Question: Dynamically add/create subplots in matplotlib I want to create a plot consisting of several subplots with shared x/y axes. It should look something like this from the documentation (though my subplots will be scatterblots): (code here) But I want to create the subplots dynamically! So the number of subplots depends on the output of a previous function. (It will probably be around 3 to 15 subplots per diagram, each from a distinct dataset, depending on the input of my script.) Can anyone tell me how to accomplish that?

Response:
Suppose you know total subplots and total columns you want to use:
```
import matplotlib.pyplot as plt

# Subplots are organized in a Rows x Cols Grid
# Tot and Cols are known

Tot = number_of_subplots
Cols = number_of_columns

# Compute Rows required

Rows = Tot // Cols

#     EDIT for correct number of rows:
#     If one additional row is necessary -> add one:

if Tot % Cols != 0:
    Rows += 1

# Create a Position index

Position = range(1,Tot + 1)
```
First instance of Rows accounts only for rows completely filled by subplots, then is added one more Row if 1 or 2 or ... Cols - 1 subplots still need location. Then create figure and add subplots with a for loop.
```
# Create main figure

fig = plt.figure(1)
for k in range(Tot):

  # add every single subplot to the figure with a for loop

  ax = fig.add_subplot(Rows,Cols,Position[k])
  ax.plot(x,y)      # Or whatever you want in the subplot

plt.show()
```
Please note that you need the range Position to move the subplots into the right place.


Question:
How to add percentages on top of grouped bars Given the following count plot how do I place percentages on top of the bars?
```
import seaborn as sns
sns.set(style="darkgrid")
titanic = sns.load_dataset("titanic")
ax = sns.countplot(x="class", hue="who", data=titanic)
```
For example for "First" I want total First men/total First, total First women/total First, and total First children/total First on top of their respective bars.

Response:
The seaborn.catplot organizing function returns a FacetGrid, which gives you access to the fig, the ax, and its patches. If you add the labels when nothing else has been plotted you know which bar-patches came from which variables. From @LordZsolt's answer I picked up the order argument to catplot: I like making that explicit because now we aren't relying on the barplot function using the order we think of as default.
```
import seaborn as sns
from itertools import product

titanic = sns.load_dataset("titanic")

class_order = ['First','Second','Third']
hue_order = ['child', 'man', 'woman']
bar_order = product(class_order, hue_order)

catp = sns.catplot(data=titanic, kind='count',
                   x='class', hue='who',
                   order = class_order,
                   hue_order = hue_order )

# As long as we haven't plotted anything else into this axis,
# we know the rectangles in it are our barplot bars
# and we know the order, so we can match up graphic and calculations:

spots = zip(catp.ax.patches, bar_order)
for spot in spots:
    class_total = len(titanic[titanic['class']==spot[1][0]])
    class_who_total = len(titanic[(titanic['class']==spot[1][0]) &
        (titanic['who']==spot[1][1])])
    height = spot[0].get_height()
    catp.ax.text(spot[0].get_x(), height+3, '{:1.2f}'.format(class_who_total/class_total))

    #checking the patch order, not for final:
    #catp.ax.text(spot[0].get_x(), -3, spot[1][0][0]+spot[1][1][0])
```
produces An alternate approach is to do the sub-summing explicitly, e.g. with the excellent pandas, and plot with matplotlib, and also do the styling yourself. (Though you can get quite a lot of styling from sns context even when using matplotlib plotting functions. Try it out -- )


Question:
How to adjust transparency (alpha) in seaborn pairplot? I can create beatiful scatter plot with seaborns regplot, obtain the right level of transparency through the scatter_kws as in
```
sns.regplot(x='logAssets', y='logLTIFR', lowess=True, data=df, scatter_kws={'alpha':0.15}, line_kws={'color': 'red'})
```
and obtain this: Is there an option in a seaborn pairplot to tweak transparency?

Response:
Ok I was very close to the solution. Seaborn pairplots have plot_kws that takes as arguments a dictionary of the kind of modifications you would do in a regplot. The following line is exactly what I needed:
```
g = sns.pairplot(df, kind='reg', plot_kws={'line_kws':{'color':'red'}, 'scatter_kws': {'alpha': 0.1}})
```
And this is the outcome: If you don't do the regression but just the scatter plot (kind='scatter'), within plot keywords you don't have to do the division between line and scatter keywords:
```
g = sns.pairplot(df, kind='scatter', plot_kws={'alpha':0.1})
```


Question:
How to put text outside of plots I am plotting two time series and computing varies indices for them. How to write these indices for these plots outside the plot using annotation or text in python? Below is my code
```
import matplotlib.pyplot as plt

obs_graph=plt.plot(obs_df['cms'], '-r', label='Observed')
plt.legend(loc='best')
plt.hold(True)
sim_graph=plt.plot(sim_df['cms'], '-g', label="Simulated")
plt.legend(loc='best')
plt.ylabel('Daily Discharge (m^3/s)')
plt.xlabel('Year')
plt.title('Observed vs Simulated Daily Discharge')
textstr = 'NSE=%.2f\nRMSE=%.2f\n'%(NSE, RMSE)
# print textstr
plt.text(2000, 2000, textstr, fontsize=14)
plt.grid(True)
plt.show()
```
I want to print teststr outside the plots. Here is the current plot:

Response:
It's probably best to define the position in figure coordinates instead of data coordinates as you'd probably not want the text to change its position when changing the data. Using figure coordinates can be done either by specifying the figure transform (fig.transFigure)
```
plt.text(0.02, 0.5, textstr, fontsize=14, transform=plt.gcf().transFigure)
```
or by using the text method of the figure instead of that of the axes.
```
plt.gcf().text(0.02, 0.5, textstr, fontsize=14)
```
In both cases the coordinates to place the text are in figure coordinates, where (0,0) is the bottom left and (1,1) is the top right of the figure. At the end you still may want to provide some extra space for the text to fit next to the axes, using plt.subplots_adjust(left=0.3) or so.


Question:
How to increase/reduce the fontsize of x and y tick labels [duplicate] This question already has answers here: How to change tick label font size (10 answers) Closed 1 year ago. I seem to have a problem in figuring out how to increase or decrease the fontsize of both the x and y tick labels while using matplotlib. I am aware that there is the set_xticklabels(labels, fontdict=None, minor=False, **kwargs) function, but I failed to understand how to control the fontsize in it. I expected something somehow explicit, like
```
title_string=('My Title')
plt.suptitle(title_string, y=1.0, fontsize=17)
```
but I haven't found anything like that so far. What am I missing?

Response:
You can set the fontsize directly in the call to set_xticklabels and set_yticklabels (as noted in previous answers). This will only affect one Axes at a time.
```
ax.set_xticklabels(x_ticks, rotation=0, fontsize=8)
ax.set_yticklabels(y_ticks, rotation=0, fontsize=8)
```
Note this method should only be used if you are fixing the positions of the ticks first (e.g. using ax.set_xticks). If you are not changing the tick positions from the default ones, you can just change the font size of the tick labels without changing the text using ax.tick_params
```
ax.tick_params(axis='x', labelsize=8)
ax.tick_params(axis='y', labelsize=8)
```
or
```
ax.tick_params(axis='both', labelsize=8)
```
You can also set the ticklabel font size globally (i.e. for all figures/subplots in a script) using rcParams:
```
import matplotlib.pyplot as plt

plt.rc('xtick',labelsize=8)
plt.rc('ytick',labelsize=8)
```
Or, equivalently:
```
plt.rcParams['xtick.labelsize']=8
plt.rcParams['ytick.labelsize']=8
```
Finally, if this is a setting that you would like to be set for all your matplotlib plots, you could also set these two rcParams in your matplotlibrc file:
```
xtick.labelsize      : 8 # fontsize of the x tick labels
ytick.labelsize      : 8 # fontsize of the y tick labels
```


Question:
How to plot vectors in python using matplotlib I am taking a course on linear algebra and I want to visualize the vectors in action, such as vector addition, normal vector, so on. For instance:
```
V = np.array([[1,1],[-2,2],[4,-7]])
```
In this case I want to plot 3 vectors V1 = (1,1), M2 = (-2,2), M3 = (4,-7). Then I should be able to add V1,V2 to plot a new vector V12(all together in one figure). when I use the following code, the plot is not as intended
```
import numpy as np
import matplotlib.pyplot as plt
M = np.array([[1,1],[-2,2],[4,-7]])

print("vector:1")
print(M[0,:])
# print("vector:2")
# print(M[1,:])
rows,cols = M.T.shape
print(cols)

for i,l in enumerate(range(0,cols)):
    print("Iteration: {}-{}".format(i,l))
    print("vector:{}".format(i))
    print(M[i,:])
    v1 = [0,0],[M[i,0],M[i,1]]
    # v1 = [M[i,0]],[M[i,1]]
    print(v1)
    plt.figure(i)
    plt.plot(v1)
    plt.show()
```

Response:
How about something like
```
import numpy as np
import matplotlib.pyplot as plt

V = np.array([[1,1], [-2,2], [4,-7]])
origin = np.array([[0, 0, 0],[0, 0, 0]]) # origin point

plt.quiver(*origin, V[:,0], V[:,1], color=['r','b','g'], scale=21)
plt.show()
```
Then to add up any two vectors and plot them to the same figure, do so before you call plt.show(). Something like:
```
plt.quiver(*origin, V[:,0], V[:,1], color=['r','b','g'], scale=21)
v12 = V[0] + V[1] # adding up the 1st (red) and 2nd (blue) vectors
plt.quiver(*origin, v12[0], v12[1], scale=21)
plt.show()
```
NOTE: in Python2 use origin[0], origin[1] instead of *origin


Question:
Putting arrowheads on vectors in a 3d plot I plotted the eigenvectors of some 3D-data and was wondering if there is currently (already) a way to put arrowheads on the lines? Would be awesome if someone has a tip for me.
```
import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

####################################################
# This part is just for reference if
# you are interested where the data is
# coming from
# The plot is at the bottom
#####################################################

# Generate some example data
mu_vec1 = np.array([0,0,0])
cov_mat1 = np.array([[1,0,0],[0,1,0],[0,0,1]])
class1_sample = np.random.multivariate_normal(mu_vec1, cov_mat1, 20)

mu_vec2 = np.array([1,1,1])
cov_mat2 = np.array([[1,0,0],[0,1,0],[0,0,1]])
class2_sample = np.random.multivariate_normal(mu_vec2, cov_mat2, 20)

# concatenate data for PCA
samples = np.concatenate((class1_sample, class2_sample), axis=0)

# mean values
mean_x = mean(samples[:,0])
mean_y = mean(samples[:,1])
mean_z = mean(samples[:,2])

#eigenvectors and eigenvalues
eig_val, eig_vec = np.linalg.eig(cov_mat)

################################
#plotting eigenvectors
################################

fig = plt.figure(figsize=(15,15))
ax = fig.add_subplot(111, projection='3d')

ax.plot(samples[:,0], samples[:,1], samples[:,2], 'o', markersize=10, color='green', alpha=0.2)
ax.plot([mean_x], [mean_y], [mean_z], 'o', markersize=10, color='red', alpha=0.5)
for v in eig_vec:
    ax.plot([mean_x, v[0]], [mean_y, v[1]], [mean_z, v[2]], color='red', alpha=0.8, lw=3)
ax.set_xlabel('x_values')
ax.set_ylabel('y_values')
ax.set_zlabel('z_values')

plt.title('Eigenvectors')

plt.draw()
plt.show()
```

Response:
To add arrow patches to a 3D plot, the simple solution is to use FancyArrowPatch class defined in /matplotlib/patches.py. However, it only works for 2D plot (at the time of writing), as its posA and posB are supposed to be tuples of length 2. Therefore we create a new arrow patch class, name it Arrow3D, which inherits from FancyArrowPatch. The only thing we need to override its posA and posB. To do that, we initiate Arrow3d with posA and posB of (0,0)s. The 3D coordinates xs, ys, zs was then projected from 3D to 2D using proj3d.proj_transform(), and the resultant 2D coordinates get assigned to posA and posB using .set_position() method, replacing the (0,0)s. This way we get the 3D arrow to work. The projection steps go into the .draw method, which overrides the .draw method of the FancyArrowPatch object. This might appear like a hack. However, the mplot3d currently only provides (again, only) simple 3D plotting capacity by supplying 3D-2D projections and essentially does all the plotting in 2D, which is not truly 3D.
```
import numpy as np
from numpy import *
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.patches import FancyArrowPatch
from mpl_toolkits.mplot3d import proj3d

class Arrow3D(FancyArrowPatch):
    def __init__(self, xs, ys, zs, *args, **kwargs):
        FancyArrowPatch.__init__(self, (0,0), (0,0), *args, **kwargs)
        self._verts3d = xs, ys, zs

    def draw(self, renderer):
        xs3d, ys3d, zs3d = self._verts3d
        xs, ys, zs = proj3d.proj_transform(xs3d, ys3d, zs3d, renderer.M)
        self.set_positions((xs[0],ys[0]),(xs[1],ys[1]))
        FancyArrowPatch.draw(self, renderer)

####################################################
# This part is just for reference if
# you are interested where the data is
# coming from
# The plot is at the bottom
#####################################################

# Generate some example data
mu_vec1 = np.array([0,0,0])
cov_mat1 = np.array([[1,0,0],[0,1,0],[0,0,1]])
class1_sample = np.random.multivariate_normal(mu_vec1, cov_mat1, 20)

mu_vec2 = np.array([1,1,1])
cov_mat2 = np.array([[1,0,0],[0,1,0],[0,0,1]])
class2_sample = np.random.multivariate_normal(mu_vec2, cov_mat2, 20)
```
Actual drawing. Note that we only need to change one line of your code, which add an new arrow artist:
```
# concatenate data for PCA
samples = np.concatenate((class1_sample, class2_sample), axis=0)

# mean values
mean_x = mean(samples[:,0])
mean_y = mean(samples[:,1])
mean_z = mean(samples[:,2])

#eigenvectors and eigenvalues
eig_val, eig_vec = np.linalg.eig(cov_mat1)

################################
#plotting eigenvectors
################################

fig = plt.figure(figsize=(15,15))
ax = fig.add_subplot(111, projection='3d')

ax.plot(samples[:,0], samples[:,1], samples[:,2], 'o', markersize=10, color='g', alpha=0.2)
ax.plot([mean_x], [mean_y], [mean_z], 'o', markersize=10, color='red', alpha=0.5)
for v in eig_vec:
    #ax.plot([mean_x,v[0]], [mean_y,v[1]], [mean_z,v[2]], color='red', alpha=0.8, lw=3)
    #I will replace this line with:
    a = Arrow3D([mean_x, v[0]], [mean_y, v[1]],
                [mean_z, v[2]], mutation_scale=20,
                lw=3, arrowstyle="-|>", color="r")
    ax.add_artist(a)
ax.set_xlabel('x_values')
ax.set_ylabel('y_values')
ax.set_zlabel('z_values')

plt.title('Eigenvectors')

plt.draw()
plt.show()
```
Please check this post, which inspired this question, for further details.


Question:
How to add group labels for bar charts I want to plot data of the following form, using matplotlib bar plot:
```
data = {'Room A':
           {'Shelf 1':
               {'Milk': 10,
                'Water': 20},
            'Shelf 2':
               {'Sugar': 5,
                'Honey': 6}
           },
        'Room B':
           {'Shelf 1':
               {'Wheat': 4,
                'Corn': 7},
            'Shelf 2':
               {'Chicken': 2,
                'Cow': 1}
           }
       }
```
The bar chart is supposed to look The bar groups should be visible from the labels on the x axis. Is there any way to do this with matplotlib?

Response:
Since I could not find a built-in solution for this in matplotlib, I coded my own:
```
#!/usr/bin/env python

from matplotlib import pyplot as plt

def mk_groups(data):
    try:
        newdata = data.items()
    except:
        return

    thisgroup = []
    groups = []
    for key, value in newdata:
        newgroups = mk_groups(value)
        if newgroups is None:
            thisgroup.append((key, value))
        else:
            thisgroup.append((key, len(newgroups[-1])))
            if groups:
                groups = [g + n for n, g in zip(newgroups, groups)]
            else:
                groups = newgroups
    return [thisgroup] + groups

def add_line(ax, xpos, ypos):
    line = plt.Line2D([xpos, xpos], [ypos + .1, ypos],
                      transform=ax.transAxes, color='black')
    line.set_clip_on(False)
    ax.add_line(line)

def label_group_bar(ax, data):
    groups = mk_groups(data)
    xy = groups.pop()
    x, y = zip(*xy)
    ly = len(y)
    xticks = range(1, ly + 1)

    ax.bar(xticks, y, align='center')
    ax.set_xticks(xticks)
    ax.set_xticklabels(x)
    ax.set_xlim(.5, ly + .5)
    ax.yaxis.grid(True)

    scale = 1. / ly
    for pos in xrange(ly + 1):  # change xrange to range for python3
        add_line(ax, pos * scale, -.1)
    ypos = -.2
    while groups:
        group = groups.pop()
        pos = 0
        for label, rpos in group:
            lxpos = (pos + .5 * rpos) * scale
            ax.text(lxpos, ypos, label, ha='center', transform=ax.transAxes)
            add_line(ax, pos * scale, ypos)
            pos += rpos
        add_line(ax, pos * scale, ypos)
        ypos -= .1

if __name__ == '__main__':
    data = {'Room A':
               {'Shelf 1':
                   {'Milk': 10,
                    'Water': 20},
                'Shelf 2':
                   {'Sugar': 5,
                    'Honey': 6}
               },
            'Room B':
               {'Shelf 1':
                   {'Wheat': 4,
                    'Corn': 7},
                'Shelf 2':
                   {'Chicken': 2,
                    'Cow': 1}
               }
           }
    fig = plt.figure()
    ax = fig.add_subplot(1,1,1)
    label_group_bar(ax, data)
    fig.subplots_adjust(bottom=0.3)
    fig.savefig('label_group_bar_example.png')
```
The mk_groups function takes a dictionary (or anything with an items() method, like collections.OrderedDict) and converts it to a data format that is then used to create the chart. It is basically a list of the form:
```
[ [(label, bars_to_span), ...], ..., [(tick_label, bar_value), ...] ]
```
The add_line function creates a vertical line in the subplot at the specified positions (in axes coordinates). The label_group_bar function takes a dictionary and creates the bar chart in the subplot with the labels beneath. The result from the example then looks like this. Easier or better solutions and suggestions are still very much appreciated.


Question: Scatter plot error bars (the error on each point is unique) I am attempting a scatter plot of 2 arrays for which I have a third array containing the absolute error (error in y direction) on each point. I want the error bars to between (point a - error on a) and (point a + error on a). Is there a way of achieving this with pylab and if not any ideas on how else I could do it?

Response:
This is almost like the other answer but you don't need a scatter plot at all, you can simply specify a scatter-plot-like format (fmt-parameter) for errorbar:
```
import matplotlib.pyplot as plt
x = [1, 2, 3, 4]
y = [1, 4, 9, 16]
e = [0.5, 1., 1.5, 2.]
plt.errorbar(x, y, yerr=e, fmt='o')
plt.show()
```
Result: A list of the avaiable fmt parameters can be found for example in the plot documentation:
```
character   description
'-'     solid line style
'--'    dashed line style
'-.'    dash-dot line style
':'     dotted line style
'.'     point marker
','     pixel marker
'o'     circle marker
'v'     triangle_down marker
'^'     triangle_up marker
'<'     triangle_left marker
'>'     triangle_right marker
'1'     tri_down marker
'2'     tri_up marker
'3'     tri_left marker
'4'     tri_right marker
's'     square marker
'p'     pentagon marker
'*'     star marker
'h'     hexagon1 marker
'H'     hexagon2 marker
'+'     plus marker
'x'     x marker
'D'     diamond marker
'd'     thin_diamond marker
'|'     vline marker
'_'     hline marker
```


Question:
Seaborn multiple barplots I have a pandas dataframe that looks like this:
```
class       men       woman   children
0   first   0.91468    0.667971   0.660562
1   second  0.30012    0.329380   0.882608
2   third   0.11899    0.189747   0.121259
```
How would I create a plot using seaborn that looks like this? Do I have to rearrange my data in some way? (source: mwaskom at stanford.edu)

Response:
Tested in python 3.12.0, pandas 2.1.1, matplotlib 3.8.0, seaborn 0.13.0 Reshape the DataFrame with pandas.DataFrame.melt or pandas.melt:
```
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

# convert the dataframe to a long format
dfm = pd.melt(df, id_vars="class", var_name="sex", value_name="survival rate")
dfm
Out:
    class       sex  survival rate
0   first       men       0.914680
1  second       men       0.300120
2   third       men       0.118990
3   first     woman       0.667971
4  second     woman       0.329380
5   third     woman       0.189747
6   first  children       0.660562
7  second  children       0.882608
8   third  children       0.121259
```
Consolidate the plot by creating a single facet with grouped bars, instead of multiple facets with single bars. Plot with the figure-level method sns.catplot
```
g = sns.catplot(x='class', y='survival rate', hue='sex', data=dfm, kind='bar', height=5, aspect=1)
```
Plot with the axes-level method sns.barplot
```
# the following code matches the plot produced by catplot
plt.figure(figsize=(5, 5))
ax = sns.barplot(x='class', y='survival rate', hue='sex', data=dfm)
ax.spines[['top', 'right']].set_visible(False)
sns.move_legend(ax, bbox_to_anchor=(1, 0.5), loc='center left', frameon=False)
```
Deprecated factorplot (v0.8.1 or earlier):
```
sns.factorplot(x='class', y='survival rate', hue='sex', data=df, kind='bar')
```


Question:
How to draw horizontal grid only (using pandas plot + pyplot) I would like to get only horizontal grid using pandas plot. The integrated parameter of pandas only has grid=True or grid=False, so I tried with matplotlib pyplot, changing the axes parameters, specifically with this code:
```py
import pandas as pd
import matplotlib.pyplot as plt
fig = plt.figure()
ax2 = plt.subplot()
ax2.grid(axis='x')
df.plot(kind='bar',ax=ax2, fontsize=10, sort_columns=True)
plt.show(fig)
```
But I get no grid, neither horizontal nor vertical. Is Pandas overwriting the axes? Or am I doing something wrong?

Response:
Try setting the grid after plotting the DataFrame. Also, to get the horizontal grid, you need to use ax2.grid(axis='y'). Below is an answer using a sample DataFrame. I have restructured how you define ax2 by making use of subplots.
```
import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame({'lab':['A', 'B', 'C'], 'val':[10, 30, 20]})

fig, ax2 = plt.subplots()

df.plot(kind='bar',ax=ax2, fontsize=10, sort_columns=True)
ax2.grid(axis='y')
plt.show()
```
Alternatively, you can also do the following: Use the axis object returned from the DataFrame plot directly to turn on the horizontal grid
```
fig = plt.figure()

ax2 = df.plot(kind='bar', fontsize=10, sort_columns=True)
ax2.grid(axis='y')
```
Third option as suggested by @ayorgo in the comments is to chain the two commands as
```
df.plot(kind='bar',ax=ax2, fontsize=10, sort_columns=True).grid(axis='y')
```


Question:
Rotate xtick labels in seaborn boxplot? I have a question that is basically the same as a question back from 2014 (see here). However, my script still throws an error. Here is what I do: I have a pandas dataframe with a few columns. I plot a simple boxplot comparison.
```
g = sns.boxplot(x='categories', y='oxygen', hue='target', data=df)
g.set_xticklabels(rotation=30)
```
The graph looks like this: I'd like to rotate the x-labels by 30 degrees. Hence I use g.set_xticklabels(rotation=30). However, I get the following error: set_xticklabels() missing 1 required positional argument: 'labels' I don't know how to pass the matplotlib labels argument to seaborns sns.boxplot. Any ideas?

Response:
The question you link to uses a factorplot. A factorplot returns its own class which has a method called set_xticklabels(rotation). This is different from the set_xticklabels method of the matplotlib Axes. In the linked question's answers there are also other options which you may use
```
ax = sns.boxplot(x='categories', y='oxygen', hue='target', data=df)
ax.set_xticklabels(ax.get_xticklabels(),rotation=30)
```
or
```
ax = sns.boxplot(x='categories', y='oxygen', hue='target', data=df)
plt.setp(ax.get_xticklabels(), rotation=45)
```


Question: How to space overlapping annotations I want to annotate the bars in a graph with some text but if the bars are close together and have comparable height, the annotations are above ea. other and thus hard to read (the coordinates for the annotations were taken from the bar position and height). Is there a way to shift one of them if there is a collision? Edit: The bars are very thin and very close sometimes so just aligning vertically doesn't solve the problem... A picture might clarify things:

Response:
I've written a quick solution, which checks each annotation position against default bounding boxes for all the other annotations. If there is a collision it changes its position to the next available collision free place. It also puts in nice arrows. For a fairly extreme example, it will produce this (none of the numbers overlap): Instead of this: Here is the code:
```
import numpy as np
import matplotlib.pyplot as plt
from numpy.random import *

def get_text_positions(x_data, y_data, txt_width, txt_height):
    a = zip(y_data, x_data)
    text_positions = y_data.copy()
    for index, (y, x) in enumerate(a):
        local_text_positions = [i for i in a if i[0] > (y - txt_height)
                            and (abs(i[1] - x) < txt_width * 2) and i != (y,x)]
        if local_text_positions:
            sorted_ltp = sorted(local_text_positions)
            if abs(sorted_ltp[0][0] - y) < txt_height: #True == collision
                differ = np.diff(sorted_ltp, axis=0)
                a[index] = (sorted_ltp[-1][0] + txt_height, a[index][1])
                text_positions[index] = sorted_ltp[-1][0] + txt_height
                for k, (j, m) in enumerate(differ):
                    #j is the vertical distance between words
                    if j > txt_height * 2: #if True then room to fit a word in
                        a[index] = (sorted_ltp[k][0] + txt_height, a[index][1])
                        text_positions[index] = sorted_ltp[k][0] + txt_height
                        break
    return text_positions

def text_plotter(x_data, y_data, text_positions, axis,txt_width,txt_height):
    for x,y,t in zip(x_data, y_data, text_positions):
        axis.text(x - txt_width, 1.01*t, '%d'%int(y),rotation=0, color='blue')
        if y != t:
            axis.arrow(x, t,0,y-t, color='red',alpha=0.3, width=txt_width*0.1,
                       head_width=txt_width, head_length=txt_height*0.5,
                       zorder=0,length_includes_head=True)
```
Here is the code producing these plots, showing the usage:
```
#random test data:
x_data = random_sample(100)
y_data = random_integers(10,50,(100))

#GOOD PLOT:
fig2 = plt.figure()
ax2 = fig2.add_subplot(111)
ax2.bar(x_data, y_data,width=0.00001)
#set the bbox for the text. Increase txt_width for wider text.
txt_height = 0.04*(plt.ylim()[1] - plt.ylim()[0])
txt_width = 0.02*(plt.xlim()[1] - plt.xlim()[0])
#Get the corrected text positions, then write the text.
text_positions = get_text_positions(x_data, y_data, txt_width, txt_height)
text_plotter(x_data, y_data, text_positions, ax2, txt_width, txt_height)

plt.ylim(0,max(text_positions)+2*txt_height)
plt.xlim(-0.1,1.1)

#BAD PLOT:
fig = plt.figure()
ax = fig.add_subplot(111)
ax.bar(x_data, y_data, width=0.0001)
#write the text:
for x,y in zip(x_data, y_data):
    ax.text(x - txt_width, 1.01*y, '%d'%int(y),rotation=0)
plt.ylim(0,max(text_positions)+2*txt_height)
plt.xlim(-0.1,1.1)

plt.show()
```


Question:
Arrow on a line plot I'd like to add an arrow to a line plot with matplotlib like in the plot below (drawn with pgfplots). How can I do (position and direction of the arrow should be parameters ideally)? Here is some code to experiment.
```
from matplotlib import pyplot
import numpy as np

t = np.linspace(-2, 2, 100)
plt.plot(t, np.sin(t))
plt.show()
```
Thanks.

Response:
In my experience this works best by using annotate. Thereby you avoid the weird warping you get with ax.arrow which is somehow hard to control. EDIT: I've wrapped it into a little function.
```
from matplotlib import pyplot as plt
import numpy as np

def add_arrow(line, position=None, direction='right', size=15, color=None):
    """
    add an arrow to a line.

    line:       Line2D object
    position:   x-position of the arrow. If None, mean of xdata is taken
    direction:  'left' or 'right'
    size:       size of the arrow in fontsize points
    color:      if None, line color is taken.
    """
    if color is None:
        color = line.get_color()

    xdata = line.get_xdata()
    ydata = line.get_ydata()

    if position is None:
        position = xdata.mean()
    # find closest index
    start_ind = np.argmin(np.absolute(xdata - position))
    if direction == 'right':
        end_ind = start_ind + 1
    else:
        end_ind = start_ind - 1

    line.axes.annotate('',
        xytext=(xdata[start_ind], ydata[start_ind]),
        xy=(xdata[end_ind], ydata[end_ind]),
        arrowprops=dict(arrowstyle="->", color=color),
        size=size
    )

t = np.linspace(-2, 2, 100)
y = np.sin(t)
# return the handle of the line
line = plt.plot(t, y)[0]

add_arrow(line)

plt.show()
```
It's not very intuitive but it works. You can then fiddle with the arrowprops dictionary until it looks right.


Question:
why does my colorbar have lines in it? Edit: Since this seems to be a popular post, here's the solution that seems to be working well for me. Thanks @gazzar and @mfra.
```
cbar.solids.set_rasterized(True)
cbar.solids.set_edgecolor("face")
```
Does anyone know why my colorbar has what appear to be lines in it? Or rather why is the color transition not smooth? I'm using basemap, obviously, but that shouldn't matter since it's all matplotlib calls under the hood AFAICT. I create the map doing something like
```
grays = plt.cm.get_cmap("Grays")
sc = mymap.scatter(xpoints, ypoints, s=sizes, c=color_values, cmap=grays, alpha=.75,
                   marker="o", zorder=10, vmin=0, vmax=1)
cbar = mymap.colorbar(sc, drawedges=True, location="bottom")
```
I tried without and without alpha and the result was the same. Maybe it is because my color_values array is not fine enough? Can I set the underlying values that are mapped to the colorbar somewhere? I don't see how, and I don't see this problem elsewhere. Ie., I can replicate the matplotlib show_colorbars example without this problem.

Response:
In case you create vector graphics, have you tried this (taken from http://matplotlib.org/api/pyplot_api.html?highlight=colorbar#matplotlib.pyplot.colorbar): "It is known that some vector graphics viewer (svg and pdf) renders white gaps between segments of the colorbar. This is due to bugs in the viewers not matplotlib. As a workaround the colorbar can be rendered with overlapping segments:
```
cbar = colorbar()
cbar.solids.set_edgecolor("face")
draw()
```
However this has negative consequences in other circumstances. Particularly with semi transparent images (alpha < 1) and colorbar extensions and is not enabled by default see (issue #1188)."


Question:
One colorbar for seaborn heatmaps in subplot Here is an example that shows a colorbar for each subplot:
```
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.random((10,10,)))

fig,axn = plt.subplots(2, 2, sharex=True, sharey=True)

for ax in axn.flat:
    sns.heatmap(df, ax=ax)
```
How can I remove the colorbars for each subplot? I'd like to have only one colorbar that is either vertically or horizontally oriented. I know I have access to each colorbar axes via fig.get_axes()[:-4], but how can I remove it from them entirely from the plot? I don't think there is an option to opt out of drawing the colorbar when heatmap is called.

Response:
The cbar parameter controls whether a colorbar should be added, and the cbar_ax parameter can optionally specify the axes where the colorbar should go. So, you could do:
```
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.random((10,10,)))

fig, axn = plt.subplots(2, 2, sharex=True, sharey=True)
cbar_ax = fig.add_axes([.91, .3, .03, .4])

for i, ax in enumerate(axn.flat):
    sns.heatmap(df, ax=ax,
                cbar=i == 0,
                vmin=0, vmax=1,
                cbar_ax=None if i else cbar_ax)

fig.tight_layout(rect=[0, 0, .9, 1])
```
(You'll get a warning about tight_layout here, but it actually is correct because we placed cbar_ax explicitly. If you don't like seeing the warning, you can also call tight_layout before plotting, but it won't be as tight).


Question:
Plotting a histogram from pre-counted data in Matplotlib I'd like to use Matplotlib to plot a histogram over data that's been pre-counted. For example, say I have the raw data
```
data = [1, 2, 2, 3, 4, 5, 5, 5, 5, 6, 10]
```
Given this data, I can use
```
pylab.hist(data, bins=[...])
```
to plot a histogram. In my case, the data has been pre-counted and is represented as a dictionary:
```
counted_data = {1: 1, 2: 2, 3: 1, 4: 1, 5: 4, 6: 1, 10: 1}
```
Ideally, I'd like to pass this pre-counted data to a histogram function that lets me control the bin widths, plot range, etc, as if I had passed it the raw data. As a workaround, I'm expanding my counts into the raw data:
```
data = list(chain.from_iterable(repeat(value, count)
            for (value, count) in counted_data.iteritems()))
```
This is inefficient when counted_data contains counts for millions of data points. Is there an easier way to use Matplotlib to produce a histogram from my pre-counted data? Alternatively, if it's easiest to just bar-plot data that's been pre-binned, is there a convenience method to "roll-up" my per-item counts into binned counts?

Response:
You can use the weights keyword argument to np.histgram (which plt.hist calls underneath)
```
val, weight = zip(*[(k, v) for k,v in counted_data.items()])
plt.hist(val, weights=weight)
```
Assuming you only have integers as the keys, you can also use bar directly:
```
min_bin = np.min(counted_data.keys())
max_bin = np.max(counted_data.keys())

bins = np.arange(min_bin, max_bin + 1)
vals = np.zeros(max_bin - min_bin + 1)

for k,v in counted_data.items():
    vals[k - min_bin] = v

plt.bar(bins, vals, ...)
```
where ... is what ever arguments you want to pass to bar (doc) If you want to re-bin your data see Histogram with separate list denoting frequency


Question: Difference between plt.draw() and plt.show() in matplotlib I was wondering why some people put a plt.draw() into their code before the plt.show(). For my code, the behavior of the plt.draw() didn't seem to change anything about the output. I did a search on the internet but couldn't find anything useful. (assuming we imported pyplot as from matplotlib import pyplot as plt)

Response: plt.show() will display the current figure that you are working on. plt.draw() will re-draw the figure. This allows you to work in interactive mode and, should you have changed your data or formatting, allow the graph itself to change. The plt.draw docs state: This is used in interactive mode to update a figure that has been altered using one or more plot object method calls; it is not needed if figure modification is done entirely with pyplot functions, if a sequence of modifications ends with a pyplot function, or if matplotlib is in non-interactive mode and the sequence of modifications ends with show() or savefig(). This seems to suggest that using plt.draw() before plt.show() when not in interactive mode will be redundant the vast majority of the time. The only time you may need it is if you are doing some very strange modifications that don't involve using pyplot functions. Refer to the Matplotlib doc, "Interactive figures" for more information.


Question:
AttributeError while adding colorbar in matplotlib The following code fails to run on Python 2.5.4:
```
from matplotlib import pylab as pl
import numpy as np

data = np.random.rand(6,6)
fig = pl.figure(1)
fig.clf()
ax = fig.add_subplot(1,1,1)
ax.imshow(data, interpolation='nearest', vmin=0.5, vmax=0.99)
pl.colorbar()

pl.show()
```
The error message is
```
C:\temp>python z.py
Traceback (most recent call last):
  File "z.py", line 10, in <module>
    pl.colorbar()
  File "C:\Python25\lib\site-packages\matplotlib\pyplot.py", line 1369, in colorbar
    ret = gcf().colorbar(mappable, cax = cax, ax=ax, **kw)
  File "C:\Python25\lib\site-packages\matplotlib\figure.py", line 1046, in colorbar
    cb = cbar.Colorbar(cax, mappable, **kw)
  File "C:\Python25\lib\site-packages\matplotlib\colorbar.py", line 622, in __init__
    mappable.autoscale_None() # Ensure mappable.norm.vmin, vmax
AttributeError: 'NoneType' object has no attribute 'autoscale_None'
```
How can I add colorbar to this code? Following is the interpreter information:
```
Python 2.5.4 (r254:67916, Dec 23 2008, 15:10:54) [MSC v.1310 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
```

Response:
(This is a very old question I know) The reason you are seeing this issue is because you have mixed the use of the state machine (matplotlib.pyplot) with the OO approach of adding images to an axes. The plt.imshow function differs from the ax.imshow method in just one subtly different way. The method ax.imshow: creates and returns an Image which has been added to the axes The function plt.imshow: creates and returns an Image which has been added to the current axes, and sets the image to be the "current" image/mappable (which can then be automatically picked up by the plt.colorbar function). If you want to be able to use the plt.colorbar (which in all but the most extreme cases, you do) with the ax.imshow method, you will need to pass the returned image (which is an instance of a ScalarMappable) to plt.colorbar as the first argument:
```
plt.imshow(image_file)
plt.colorbar()
```
is equivalent (without using the state machine) to:
```
img = ax.imshow(image_file)
plt.colorbar(img, ax=ax)
```
If ax is the current axes in pyplot, then the kwarg ax=ax is not needed.


Question:
How to save the Pandas dataframe/series data as a figure? It sounds somewhat weird， but I need to save the Pandas console output string to png pics. For example:
```

```python
df
#Output
#                   sales  net_pft     ROE    ROIC
#STK_ID RPT_Date
#600809 20120331  22.1401   4.9253  0.1651  0.6656
#       20120630  38.1565   7.8684  0.2567  1.0385
#       20120930  52.5098  12.4338  0.3587  1.2867
#       20121231  64.7876  13.2731  0.3736  1.2205
#       20130331  27.9517   7.5182  0.1745  0.3723
#       20130630  40.6460   9.8572  0.2560  0.4290
#       20130930  53.0501  11.8605  0.2927  0.4369
#```
#Is there any way like df.output_as_png(filename='df_data.png') to generate a pic file which just display above content inside?
```

Response:
Option-1: use matplotlib table functionality, with some additional styling:
```
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

df = pd.DataFrame()
df['date'] = ['2016-04-01', '2016-04-02', '2016-04-03']
df['calories'] = [2200, 2100, 1500]
df['sleep hours'] = [8, 7.5, 8.2]
df['gym'] = [True, False, False]

def render_mpl_table(data, col_width=3.0, row_height=0.625, font_size=14,
                     header_color='#40466e', row_colors=['#f1f1f2', 'w'], edge_color='w',
                     bbox=[0, 0, 1, 1], header_columns=0,
                     ax=None, **kwargs):
    if ax is None:
        size = (np.array(data.shape[::-1]) + np.array([0, 1])) * np.array([col_width, row_height])
        fig, ax = plt.subplots(figsize=size)
        ax.axis('off')
    mpl_table = ax.table(cellText=data.values, bbox=bbox, colLabels=data.columns, **kwargs)
    mpl_table.auto_set_font_size(False)
    mpl_table.set_fontsize(font_size)

    for k, cell in mpl_table._cells.items():
        cell.set_edgecolor(edge_color)
        if k[0] == 0 or k[1] < header_columns:
            cell.set_text_props(weight='bold', color='w')
            cell.set_facecolor(header_color)
        else:
            cell.set_facecolor(row_colors[k[0]%len(row_colors) ])
    return ax.get_figure(), ax

fig,ax = render_mpl_table(df, header_columns=0, col_width=2.0)
fig.savefig("table_mpl.png")
```
Options-2 Use Plotly + kaleido
```
import plotly.figure_factory as ff
import pandas as pd

df = pd.DataFrame()
df['date'] = ['2016-04-01', '2016-04-02', '2016-04-03']
df['calories'] = [2200, 2100, 1500]
df['sleep hours'] = [8, 7.5, 8.2]
df['gym'] = [True, False, False]

fig =  ff.create_table(df)
fig.update_layout(
    autosize=False,
    width=500,
    height=200,
)
fig.write_image("table_plotly.png", scale=2)
fig.show()
```
For the above, the font size can be changed using the font attribute:
```
fig.update_layout(
    autosize=False,
    width=500,
    height=200,
    font={'size':8}
)
```


Question:
ValueError: Unknown projection '3d' (once again) When executing this line of code:
```
import matplotlib.pyplot as plt

#your code

fig = plt.figure()
ax = fig.gca(projection='3d')
```
I have an output error:
```
raise ValueError("Unknown projection %r" % projection)

ValueError: Unknown projection '3d'

<Figure size 432x288 with 0 Axes>
```
The error appears also when I use Spyder as IDE. The version of matplotlib is
```
print('matplotlib: {}'.format(matplotlib.__version__))
matplotlib: 1.5.0rc3
```
But I had the same problem even with other versions of matplotlib. A similar error was reported in this question (Stackoverflow) but the answers do not help. Some suggestions on how to modify the instruction? matplotlib: 3.0.2

Response:
You will have to import Axes3D to enable the 3d plotting in matplotlib. The official tutorials on 3d plotting can be found here. So the correct imports and code would look like
```
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D # <--- This is important for 3d plotting

#your code

fig = plt.figure()
ax = fig.gca(projection='3d')
```


Question:
Matplotlib boxplot without outliers Is there any way of hiding the outliers when plotting a boxplot in matplotlib (python)? I'm using the simplest way of plotting it:
```
from pylab import *
  boxplot([1,2,3,4,5,10])
  show()
```
This gives me the following plot: (I cannot post the image because I have not enough reputation, but basically it is a boxplot with Q1 at y=1, Q3 at y=5, and the outlier at y=10) I would like to remove the outlier at y=10, so that the plot only shows from Q1 to Q3 (in this case from 1 to 5).

Response:
In current versions of matplotlib you can do:
```
boxplot([1,2,3,4,5,10], showfliers=False)
```
or
```
boxplot([1,2,3,4,5,10], sym='')
```
In older versions, only the second approach will work. The docs for boxplot do mention this, btw as, "Enter an empty string (‘’) if you don’t want to show fliers.", though, at least for myself, "outliers" is the more familiar word.


Question: Changing the background color of the axes planes of a 3D plot On the basis of the scatterplot example of matplotlib, how can I change the gray background color of the 3 axes grid planes? I would like to set it to white, keeping the grid lines with the default gray color. I found this question but I couldn't apply it to the example. Thanks.

Response:
For a slightly different approach, see below:
```
# Get rid of colored axes planes
# First remove fill
ax.xaxis.pane.fill = False
ax.yaxis.pane.fill = False
ax.zaxis.pane.fill = False

# Now set color to white (or whatever is "invisible")
ax.xaxis.pane.set_edgecolor('w')
ax.yaxis.pane.set_edgecolor('w')
ax.zaxis.pane.set_edgecolor('w')

# Bonus: To get rid of the grid as well:
ax.grid(False)
```
See this blog post that I used as my source.


Question:
How to set the line width of error bar caps How can the line width of the error bar caps in Matplotlib be changed? I tried the following code:
```
(_, caplines, _) = matplotlib.pyplot.errorbar(
    data['distance'], data['energy'], yerr=data['energy sigma'],
    capsize=10, elinewidth=3)

for capline in caplines:
    capline.set_linewidth(10)
    capline.set_color('red')

pp.draw()
```
Unfortunately, this updates the color of the caps, but does not update the line width of the caps! The resulting effect is similar to the "fat error bar lines / thin caps" in the following image: It would be nice to have "fat" bar caps, in the case; how can this be done, in Matplotlib? Drawing the bar caps "manually", one by one with plot() would work, but a simpler alternative would be best.

Response:
EOL, you were very close..,
```
distance = [1,3,7,9]
energy = [10,20,30,40]
sigma = [1,3,2,5]

(_, caps, _) = plt.errorbar(distance, energy, sigma, capsize=20, elinewidth=3)

for cap in caps:
    cap.set_color('red')
    cap.set_markeredgewidth(10)

plt.show
```
set_markeredgewidth sets the width of the cap lines. Matplotlib objects have so many attributes that often it is difficult to remember the right ones for a given object. IPython is a very useful tool for introspecting matplotlib. I used it to analyze the properties of the 2Dlines correponding to the error cap lines and I found that and other marker properties. Cheers


Question:
Hiding Axis Labels I'm trying to hide the axis labels on the first subplot at 211. I'd like to label the figure, not just a subplot (reference: "Isub Event Characteristics"). How can I control font properties like size, font, color?
```
f = Figure()

vdsvgsPlot = f.add_subplot(211)
vdsvgsPlot.plot(theLister()[3],theLister()[0])
vdsvgsPlot.plot(theLister()[3],theLister()[1])

isubPlot = f.add_subplot(212)
isubPlot.plot(theLister()[3],theLister()[2])

plotCanvas = FigureCanvasTkAgg(f, master)
toolbar = NavigationToolbar2TkAgg(plotCanvas, master)

plotCanvas.get_tk_widget().pack()
```
Thank you in advance.

Response: You have several different questions here... Let me break them up a bit... By "hide the axis labels on the first subplot" do you mean the actual axis labels (which aren't there unless you specify them), the tick labels (i.e. the numbers along the axis), the axis ticks, or all of the above? If you mean "all of the above", just do ax.xaxis.set_visible(False) and the same for the y-axis. (ax here would be vdsvgsPlot in your example code above) If you mean the axis tick labels, just set them to [], i.e.: ax.set_xticklabels([]). (and set_yticklabels for the y-axis) If you mean the axis ticks, you can do something similar: ax.set_xticks([]) and ax.set_yticks([]) which will turn off both the ticks and ticklabels. As to the second question, use suptitle to title the entire figure. i.e.: fig.suptitle('whatever') (f.suptitle... in your example code above). As for how to control the font properties, you can either pass various keyword arguments to suptitle (or anything else that creates text on a plot) or set them after you create the text. For example fig.suptitle('This is a title', size=20, horizontalalignment='left', font='Times', color='red') In general, I would suggest you look through the various user's guide, gallery of examples (all of which have the source code included), the pyplot api docs, and the detailed api docs.


Question:
Plot Normal distribution with Matplotlib [duplicate] This question already has answers here: How to plot normal distribution (10 answers) Closed 3 years ago. please help me to plot the normal distribution of the folowing data: DATA:
```
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm

h = [186, 176, 158, 180, 186, 168, 168, 164, 178, 170, 189, 195, 172,
     187, 180, 186, 185, 168, 179, 178, 183, 179, 170, 175, 186, 159,
     161, 178, 175, 185, 175, 162, 173, 172, 177, 175, 172, 177, 180]

std = np.std(h)
mean = np.mean(h)
plt.plot(norm.pdf(h,mean,std))
```
output:
```
Standard Deriviation = 8.54065575872
mean = 176.076923077
```
the plot is incorrect, what is wrong with my code?

Response:
Note: This solution is using pylab, not matplotlib.pyplot You may try using hist to put your data info along with the fitted curve as below:
```
import numpy as np
import scipy.stats as stats
import pylab as pl

h = sorted([186, 176, 158, 180, 186, 168, 168, 164, 178, 170, 189, 195, 172,
     187, 180, 186, 185, 168, 179, 178, 183, 179, 170, 175, 186, 159,
     161, 178, 175, 185, 175, 162, 173, 172, 177, 175, 172, 177, 180])  #sorted

fit = stats.norm.pdf(h, np.mean(h), np.std(h))  #this is a fitting indeed

pl.plot(h,fit,'-o')

pl.hist(h,normed=True)      #use this to draw histogram of your data

pl.show()                   #use may also need add this
```


Question:
Hide axis label only, not entire axis, in Pandas plot I can clear the text of the xlabel in a Pandas plot with:
```py
plt.xlabel("")
```
Instead, is it possible to hide the label? May be something like .xaxis.label.set_visible(False).

Response:
From the Pandas docs - The plot method on Series and DataFrame is just a simple wrapper around plt.plot(): This means that anything you can do with matplolib, you can do with a Pandas DataFrame plot. pyplot has an axis() method that lets you set axis properties. Calling plt.axis('off') before calling plt.show() will turn off both axes.
```
df.plot()
plt.axis('off')
plt.show()
plt.close()
```
To control a single axis, you need to set its properties via the plot's Axes. For the x axis - (pyplot.axes().get_xaxis().....)
```
df.plot()
ax1 = plt.axes()
x_axis = ax1.axes.get_xaxis()
x_axis.set_visible(False)
plt.show()
plt.close()
```
Similarly to control an axis label, get the label and turn it off.
```
df.plot()
ax1 = plt.axes()
x_axis = ax1.axes.get_xaxis()
x_axis.set_label_text('foo')
x_label = x_axis.get_label()
##print isinstance(x_label, matplotlib.artist.Artist)
x_label.set_visible(False)
plt.show()
plt.close()
```
You can also get to the x axis like this
```
ax1 = plt.axes()
x_axis = ax1.xaxis
x_axis.set_label_text('foo')
x_axis.label.set_visible(False)
```
Or this
```
ax1 = plt.axes()
ax1.xaxis.set_label_text('foo')
ax1.xaxis.label.set_visible(False)
```
DataFrame.plot returns a matplotlib.axes.Axes or numpy.ndarray of them so you can get it/them when you call it.
```
axs = df.plot()
```
.set_visible() is an Artist method. The axes and their labels are Artists so they have Artist methods/attributes as well as their own. There are many ways to customize your plots. Sometimes you can find the feature you want browsing the Gallery and Examples


Question: Non-ASCII characters in Matplotlib I have a problem displaying non-ASCII characters in Matplotlib, these characters are rendered as small boxes instead of a proper font, it looks like (I filled these boxes with red paint to hightlight them): How do I fix it? A related question is Accented characters in Matplotlib.

Response:
This problem may actually have a couple of different causes: The default font does not include these glyphs You may change the default font using the following (before any plotting is done!)
```
matplotlib.rc('font', family='Arial')
```
In some versions of matplotlib you'll have to set the family:
```
matplotlib.rc('font', **{'sans-serif' : 'Arial',
                         'family' : 'sans-serif'})
```
(Note that because sans-serif contains a hyphen inside the **{} syntax, it is actually necessary.) The first command changes the sans-serif font family to contain only one font (in my case it was Arial), the second sets the default font family to sans-serif. Other options are included in the documentation. You have improperly created/passed string objects into Matplotlib Even if the font contains proper glyphs, if you forgot to use u to create Unicode constants, Matplotlib will have this behaviour:
```
plt.xlabel("Średnia odległość między stacjami wsparcia a modelowaną [km]")
```
So you need to add u:
```
plt.xlabel(u"Średnia odległość między stacjami wsparcia a modelowaną [km]")
```
Another cause is that you forgot to put a UTF-8 magic comment on top of the file (I read that this might be the source of the problem):
```
# -*- coding: utf-8 -*-
```


Question:
Specify figure size in centimeter in matplotlib I am wondering whether you can specify the size of a figure in matplotlib in centimeter. At the moment I write:
```
def cm2inch(value):
    return value/2.54

fig = plt.figure(figsize=(cm2inch(12.8), cm2inch(9.6)))
```
But is there a native approach?

Response:
This is not an answer to the question ''Is there a native way?'', but I think that there is a more elegant way:
```py
def cm2inch(*tupl):
    inch = 2.54
    if isinstance(tupl[0], tuple):
        return tuple(i/inch for i in tupl[0])
    else:
        return tuple(i/inch for i in tupl)
```
Then one can issue plt.figure(figsize=cm2inch(12.8, 9.6)), which I think is a much cleaner way. The implementation also allows us to use cm2inch((12.8, 9.6)), which I personally do not prefer, but some people may do. Even though there isn't any way of doing this natively at the moment, I found a discussion here.


Question:
Multiple histograms in Pandas I would like to create the following histogram (see image below) taken from the book "Think Stats". However, I cannot get them on the same plot. Each DataFrame takes its own subplot. I have the following code:
```
import nsfg
import matplotlib.pyplot as plt
df = nsfg.ReadFemPreg()
preg = nsfg.ReadFemPreg()
live = preg[preg.outcome == 1]

first = live[live.birthord == 1]
others = live[live.birthord != 1]

#fig = plt.figure()
#ax1 = fig.add_subplot(111)

first.hist(column = 'prglngth', bins = 40, color = 'teal', \
           alpha = 0.5)
others.hist(column = 'prglngth', bins = 40, color = 'blue', \
            alpha = 0.5)
plt.show()
```
The above code does not work when I use ax = ax1 as suggested in: pandas multiple plots not working as hists nor this example does what I need: Overlaying multiple histograms using pandas. When I use the code as it is, it creates two windows with histograms. Any ideas how to combine them? Here's an example of how I'd like the final figure to look:

Response:
As far as I can tell, pandas can't handle this situation. That's ok since all of their plotting methods are for convenience only. You'll need to use matplotlib directly. Here's how I do it:
```
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
import pandas
#import seaborn
#seaborn.set(style='ticks')

np.random.seed(0)
df = pandas.DataFrame(np.random.normal(size=(37,2)), columns=['A', 'B'])
fig, ax = plt.subplots()

a_heights, a_bins = np.histogram(df['A'])
b_heights, b_bins = np.histogram(df['B'], bins=a_bins)

width = (a_bins[1] - a_bins[0])/3

ax.bar(a_bins[:-1], a_heights, width=width, facecolor='cornflowerblue')
ax.bar(b_bins[:-1]+width, b_heights, width=width, facecolor='seagreen')
#seaborn.despine(ax=ax, offset=10)
```
And that gives me:


Question:
Setting axes.linewidth without changing the rcParams global dict So, it seems one cannot do the following (it raises an error, since axes does not have a set_linewidth method):
```
axes_style = {'linewidth':5}
axes_rect = [0.1, 0.1, 0.9, 0.9]

axes(axes_rect, **axes_style)
```
and has to use the following old trick instead:
```
rcParams['axes.linewidth'] = 5 # set the value globally

... # some code

rcdefaults() # restore [global] defaults
```
Is there an easy / clean way (may be one can set x- and y- axes parameters individually, etc)? If no, why?

Response:
This answer does not work, as it is explained in the comments. I suggest using spines. As mentioned in a comment by Czechnology, consider changing the ticks too.
```py
import matplotlib.pyplot as plt

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 4))

ax1.set_title('Normal spine and ticks')
ax2.set_title('Adjusted spine and ticks')

# change each spine separately:
# ax.spines['right'].set_linewidth(0.5)

# change all spines
for axis in ['top','bottom','left','right']:
    ax2.spines[axis].set_linewidth(4)

# increase tick width
ax2.tick_params(width=4)

plt.show()
```
see more about spines at: http://matplotlib.org/api/spines_api.html http://matplotlib.org/examples/pylab_examples/multiple_yaxis_with_spines.html


Question: matplotlib: disregard outliers when plotting I'm plotting some data from various tests. Sometimes in a test I happen to have one outlier (say 0.1), while all other values are three orders of magnitude smaller. With matplotlib, I plot against the range [0, max_data_value] How can I just zoom into my data and not display outliers, which would mess up the x-axis in my plot? Should I simply take the 95 percentile and have the range [0, 95_percentile] on the x-axis?

Response:
There's no single "best" test for an outlier. Ideally, you should incorporate a-priori information (e.g. "This parameter shouldn't be over x because of blah..."). Most tests for outliers use the median absolute deviation, rather than the 95th percentile or some other variance-based measurement. Otherwise, the variance/stddev that is calculated will be heavily skewed by the outliers. Here's a function that implements one of the more common outlier tests.
```
def is_outlier(points, thresh=3.5):
    """
    Returns a boolean array with True if points are outliers and False
    otherwise.

    Parameters:
    -----------
        points : An numobservations by numdimensions array of observations
        thresh : The modified z-score to use as a threshold. Observations with
            a modified z-score (based on the median absolute deviation) greater
            than this value will be classified as outliers.

    Returns:
    --------
        mask : A numobservations-length boolean array.

    References:
    ----------
        Boris Iglewicz and David Hoaglin (1993), "Volume 16: How to Detect and
        Handle Outliers", The ASQC Basic References in Quality Control:
        Statistical Techniques, Edward F. Mykytka, Ph.D., Editor.
    """
    if len(points.shape) == 1:
        points = points[:,None]
    median = np.median(points, axis=0)
    diff = np.sum((points - median)**2, axis=-1)
    diff = np.sqrt(diff)
    med_abs_deviation = np.median(diff)

    modified_z_score = 0.6745 * diff / med_abs_deviation

    return modified_z_score > thresh
```
As an example of using it, you'd do something like the following:
```
import numpy as np
import matplotlib.pyplot as plt

# The function above... In my case it's in a local utilities module
from sci_utilities import is_outlier

# Generate some data
x = np.random.random(100)

# Append a few "bad" points
x = np.r_[x, -3, -10, 100]

# Keep only the "good" points
# "~" operates as a logical not operator on boolean numpy arrays
filtered = x[~is_outlier(x)]

# Plot the results
fig, (ax1, ax2) = plt.subplots(nrows=2)

ax1.hist(x)
ax1.set_title('Original')

ax2.hist(filtered)
ax2.set_title('Without Outliers')

plt.show()
```


Question:
How to format axis tick labels from number to thousands or Millions (125,436 to 125.4K)
```
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import seaborn as sns
import pandas as pd
sns.set(style="darkgrid")
fig, ax = plt.subplots(figsize=(8, 5))
palette = sns.color_palette("bright", 6)
g = sns.scatterplot(ax=ax, x="Area", y="Rent/Sqft", hue="Region", marker='o', data=df, s=100, palette= palette)
g.legend(bbox_to_anchor=(1, 1), ncol=1)
g.set(xlim = (50000,250000))
```
How can I can change the axis format from a number to custom format? For example, 125000 to 125.00K

Response:
IIUC you can format the xticks and set these:
```

```python
#generate some psuedo data
df = pd.DataFrame({'num':[50000, 75000, 100000, 125000], 'Rent/Sqft':np.random.randn(4), 'Region':list('abcd')})
df
#Output
#num  Rent/Sqft Region
#0   50000   0.109196      a
#1   75000   0.566553      b
#2  100000  -0.274064      c
#3  125000  -0.636492      d
```

```python
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import seaborn as sns
import pandas as pd
sns.set(style="darkgrid")
fig, ax = plt.subplots(figsize=(8, 5))
palette = sns.color_palette("bright", 4)
g = sns.scatterplot(ax=ax, x="num", y="Rent/Sqft", hue="Region", marker='o', data=df, s=100, palette= palette)
g.legend(bbox_to_anchor=(1, 1), ncol=1)
g.set(xlim = (50000,250000))
xlabels = ['{:,.2f}'.format(x) + 'K' for x in g.get_xticks()/1000]
g.set_xticklabels(xlabels)
#Output
#```
#The key bit here is this line:
#```
#xlabels = ['{:,.2f}'.format(x) + 'K' for x in g.get_xticks()/1000]
#g.set_xticklabels(xlabels)
#```
#So this divides all the ticks by 1000 and then formats them and sets the xtick labels UPDATE Thanks to @ScottBoston who has suggested a better method:
#```
#ax.xaxis.set_major_formatter(ticker.FuncFormatter(lambda x, pos: '{:,.2f}'.format(x/1000) + 'K'))
#```
#see the docs
```


Question:
How to create a stacked bar chart for my DataFrame using seaborn [duplicate] This question already has answers here: How to have clusters of stacked bars (10 answers) Closed 7 years ago. I have a DataFrame df:
```py
df = pd.DataFrame(columns=["App","Feature1", "Feature2","Feature3", "Feature4","Feature5", "Feature6","Feature7","Feature8"], data=[['SHA', 0, 0, 1, 1, 1, 0, 1, 0], ['LHA', 1, 0, 1, 1, 0, 1, 1, 0], ['DRA', 0, 0, 0, 0, 0, 0, 1, 0], ['FRA', 1, 0, 1, 1, 1, 0, 1, 1], ['BRU', 0, 0, 1, 0, 1, 0, 0, 0], ['PAR', 0, 1, 1, 1, 1, 0, 1, 0], ['AER', 0, 0, 1, 1, 0, 1, 1, 0], ['SHE', 0, 0, 0, 1, 0, 0, 1, 0]])

# display(df)
   App  Feature1  Feature2  Feature3  Feature4  Feature5  Feature6  Feature7  Feature8
0  SHA         0         0         1         1         1         0         1         0
1  LHA         1         0         1         1         0         1         1         0
2  DRA         0         0         0         0         0         0         1         0
3  FRA         1         0         1         1         1         0         1         1
4  BRU         0         0         1         0         1         0         0         0
5  PAR         0         1         1         1         1         0         1         0
6  AER         0         0         1         1         0         1         1         0
7  SHE         0         0         0         1         0         0         1         0
```
I want to create a stacked bar chart so that each stack would correspond to App while the Y axis would contain the count of 1 values and the X axis would be Feature. It should be similar to this bar chart with the only difference that now I want to see stack bars and a legend with colors:
```py
df_c = df.iloc[:, 1:].eq(1).sum().rename_axis('Feature').reset_index(name='Count')
df_c = df_c.sort_values('Count')
plt.figure(figsize=(12,8))
ax = sns.barplot(x="Feature", y='Count', data=df_c, palette=sns.color_palette("GnBu", 10))
plt.xticks(rotation='vertical')
ax.grid(b=True, which='major', color='#d3d3d3', linewidth=1.0)
ax.grid(b=True, which='minor', color='#d3d3d3', linewidth=0.5)
plt.show()
```

Response:
You could use pandas plot as @Bharath suggest:
```
import seaborn as sns
sns.set()
df.set_index('App').T.plot(kind='bar', stacked=True)
```
Output: Updated: from matplotlib.colors import ListedColormap df.set_index('App')\ .reindex_axis(df.set_index('App').sum().sort_values().index, axis=1)\ .T.plot(kind='bar', stacked=True, colormap=ListedColormap(sns.color_palette("GnBu", 10)), figsize=(12,6)) Updated Pandas 0.21.0+ reindex_axis is deprecated, use reindex
```
from matplotlib.colors import ListedColormap

df.set_index('App')\
  .reindex(df.set_index('App').sum().sort_values().index, axis=1)\
  .T.plot(kind='bar', stacked=True,
          colormap=ListedColormap(sns.color_palette("GnBu", 10)),
          figsize=(12,6))
```
Output:


Question:
Draw graph in NetworkX I'm trying to draw any graph in NetworkX, but get nothing, not even errors:
```
import networkx as nx
import matplotlib.pyplot as plt
g1=nx.petersen_graph()
nx.draw(g1)
```

Response:
Add to the end:
```
plt.show()
```
```
import networkx as nx
import matplotlib.pyplot as plt
g1 = nx.petersen_graph()
nx.draw(g1)
plt.show()
```
When run from an interactive shell where plt.ion() has been called, the plt.show() is not needed. This is probably why it is omitted in a lot of examples. If you run these commands from a script (where plt.ion() has not been called), the plt.show() is needed. plt.ion() is okay for interactive sessions, but is not recommended for scripts.


Question:
Plot with fewer markers than data points (or a better way to plot CDFs?) [matplotlib, or general plotting help] I am plotting Cumulative Distribution Functions, with a large number of data points. I am plotting a few lines on the same plot, which are identified with markers as it will be printed in black and white. What I would like are markers evenly spaced in the x-dimension. What I am getting is one marker per data point (and given the number of points, they all overlap) I'm not sure if it's my understanding of how to plot well, or just a lack of understanding matplotlib. I can't find a 'marker frequency' setting. An easy solution for one line would be to take every N'th value from the line, and use that as a separate line with linestyle='', but I would like the markers to be vertically aligned, and the different x arrays have different lengths.
```
# in reality, many thousands of values
x_example = [ 567, 460, 66, 1034, 275, 26, 628, 99, 287, 157, 705, 421, 1093, \
     139, 204, 14, 240, 179, 94, 139, 645, 670, 47, 520, 891, 450, 56, 964,   \
     1728, 99, 277, 356, 1628, 745, 364, 88, 112, 810, 816, 523, 401, 89,     \
     278, 917, 370, 53, 39, 90, 853, 356 ]
x = sort(x_example)
y = linspace(0,1,len(x))

ax = subplot(1,1,1)
plots[w] = ax.plot(x,y, marker='o')
```

Response: You can do plot(x,y,marker='o',markevery=5) to mark every fifth point, but I don't think there is any built-in support for setting marks at even intervals. You could decide on the x locations where you want the marks, use e.g. numpy.searchsorted to find which data points the locations fall between, and then interpolate between the neighboring points to find the y coordinates.


Question:
Plot histogram with colors taken from colormap I want to plot a simple 1D histogram where the bars should follow the color-coding of a given colormap. Here's an MWE:
```
import numpy as n
import matplotlib.pyplot as plt

# Random gaussian data.
Ntotal = 1000
data = 0.05 * n.random.randn(Ntotal) + 0.5

# This is the colormap I'd like to use.
cm = plt.cm.get_cmap('RdYlBu_r')

# Plot histogram.
n, bins, patches = plt.hist(data, 25, normed=1, color='green')

plt.show()
```
which outputs this: Instead of the color being green for the entire histogram, I'd like the columns to follow a color-coding given by the colormap defined in cm and the values of the bins. This would mean that bins closer to zero (not in height but in position) should look bluer and those closer to one redder, according to the chosen colormap RdYlBu_r. Since plt.histo doesn't take a cmap argument I don't know how to tell it to use the colormap defined in cm.

Response:
The hist command returns a list of patches, so you can iterate over them and set their color like so:
```
import numpy as n
import matplotlib.pyplot as plt

# Random gaussian data.
Ntotal = 1000
data = 0.05 * n.random.randn(Ntotal) + 0.5

# This is the colormap I'd like to use.
cm = plt.cm.get_cmap('RdYlBu_r')

# Plot histogram.
n, bins, patches = plt.hist(data, 25, normed=1, color='green')
bin_centers = 0.5 * (bins[:-1] + bins[1:])

# scale values to interval [0,1]
col = bin_centers - min(bin_centers)
col /= max(col)

for c, p in zip(col, patches):
    plt.setp(p, 'facecolor', cm(c))

plt.show()
```
To get the colors, you need to call the colormap with a value between 0 and 1. Resulting figure:


Question: How to remove outline of circle marker when using pyplot.plot in matplotlib I'm producing a scatter plot using pyplot.plot (instead of scatter - I'm having difficulties with the colormap) I am plotting using the 'o' marker to get a circle, but the circle always has a black outline. How do I remove the outline, or adjust its colour?

Response:
To remove the outline of a marker, and adjust its color, use markeredgewidth (aka mew), and markeredgecolor (aka mec) respectively. Using this as a guide:
```
import numpy as np
import matplotlib.pyplot as plt

x = np.arange(0, 5, 0.1)
y = np.sin(x)

plt.plot(x,
         y,
         color='blue',
         marker='o',
         fillstyle='full',
         markeredgecolor='red',
         markeredgewidth=0.0)
```
This produces: As you notice, even though the marker edge color is set, because the width of it is set to zero it doesn't show up.


Question:
matplotlib Axes.plot() vs pyplot.plot() What is the difference between the Axes.plot() and pyplot.plot() methods? Does one use another as a subroutine? It seems that my options for plotting are
```
line = plt.plot(data)
```
or
```
ax = plt.axes()
line = ax.plot(data)
```
or even
```
fig = plt.figure()
ax = fig.add_axes([0,0,1,1])
line = ax.plot(data)
```
Are there situations where it is preferable to use one over the other?

Response:
For drawing a single plot, the best practice is probably
```
fig = plt.figure()
plt.plot(data)
fig.show()
```
Now, lets take a look in to 3 examples from the question and explain what they do. Takes the current figure and axes (if none exists it will create a new one) and plot into them.
```
line = plt.plot(data)
```
In your case, the behavior is same as before with explicitly stating the axes for plot.
```
ax = plt.axes()
 line = ax.plot(data)
```
This approach of using ax.plot(...) is a must, if you want to plot into multiple axes (possibly in one figure). For example when using a subplots. Explicitly creates new figure - you will not add anything to previous one. Explicitly creates a new axes with given rectangle shape and the rest is the same as with 2.
```
fig = plt.figure()
 ax = fig.add_axes([0,0,1,1])
 line = ax.plot(data)
```
possible problem using figure.add_axes is that it may add a new axes object to the figure, which will overlay the first one (or others). This happens if the requested size does not match the existing ones.


Question:
Adjust Axes3D label positioning I am having trouble with axes labels overlapping ticks labels in matplotlib. I've tried to reposition the labels "manually" by applying transforms or by calling set_y(), but no avail. Here's a snippet that reproduces the problem:
```
import matplotlib
matplotlib.use("TKAGG")
import matplotlib.pyplot as pyplot
import mpl_toolkits.mplot3d

figure = pyplot.figure()
figure.subplots_adjust(bottom=0.25, top=0.75)
axes = figure.gca(projection='3d')
xLabel = axes.set_xlabel('XXX xxxxxx xxxx x xx x')
yLabel = axes.set_ylabel('YY (y) yyyyyy')
zLabel = axes.set_zlabel('Z zzzz zzz (z)')
plot = axes.plot([1,2,3],[1,2,3])

pyplot.show()
```
Note how the x and y labels clash with the ticks. Can I solve this elegantly ?

Response:
I share your frustration. I worked on it for a good half hour and got nowhere. The docs say set_xlabel takes an arg labelpad but I get an error (AttributeError: Unknown property labelpad)! Setting it after the fact doesn't do anything, on xaxis or w_xaxis. Here's a crude workaround:
```
import matplotlib
matplotlib.use("TKAGG")
import matplotlib.pyplot as pyplot
import mpl_toolkits.mplot3d

figure = pyplot.figure(figsize=(8,4), facecolor='w')
ax = figure.gca(projection='3d')

xLabel = ax.set_xlabel('\nXXX xxxxxx xxxx x xx x', linespacing=3.2)
yLabel = ax.set_ylabel('\nYY (y) yyyyyy', linespacing=3.1)
zLabel = ax.set_zlabel('\nZ zzzz zzz (z)', linespacing=3.4)
plot = ax.plot([1,2,3],[1,2,3])
ax.dist = 10

pyplot.show()
```


Question: Matplotlib, horizontal bar chart (barh) is upside-down TL'DR, the vertical bar charts are shown in a conventional way -- things line up from left to right. However, when it is converted to horizontal bar chart (from bar to barh), everything is upside-down. I.e., for a grouped bar chart, not only the order of the grouped bar is wrong, the order of the each group is wrong as well. For e.g., the graph from http://dwheelerau.com/2014/05/28/pandas-data-analysis-new-zealanders-and-their-sheep/ If you look closely, you will find that the the bar and legend are in reverse order -- Beef shows on top in legend but on bottom in the graph. As the simplest demo, I changed kind='bar', to kind='barh', from this graph https://plot.ly/pandas/bar-charts/#pandas-grouped-bar-chart and the result looks like this: https://plot.ly/7/~xpt/ I.e., the bars in the horizontal grouped bar chart is ordered upside-down. How to fix it? EDIT: @Ajean, it is actually not only the order of the grouped bar is wrong, the order of the each group is wrong as well. The graph from Simple customization of matplotlib/pandas bar chart (labels, ticks, etc.) shows it clearly: We can see that the order is unconventional too, because people would expect the graph to be top-down, with "AAA" at the top, not the bottom. If you search for "Excel upside-down", you will find people are complaining about this in Excel all over the places. The Microsoft Excel has a fix for it, do Matplotlib/Panda/Searborn/Ploty/etc has a fix for it?

Response:
I believe the joint wrong order of groups and subgroups boils down to a single feature: that the y axis increases upwards, as in a usual plot. Try reversing the y axis of your axes as in this pandas-less example:
```py
import numpy as np
import matplotlib.pyplot as plt

x = range(5)
y = np.random.randn(5)

# plot 1: bar
plt.figure()
plt.bar(x, y)

# plot 2: barh, wrong order
plt.figure()
plt.barh(x, y)

# plot 3: barh with correct order: top-down y axis
plt.figure()
plt.barh(x, y)
plt.gca().invert_yaxis()

plt.show()
```
Specifically for pandas, pandas.DataFrame.plot and its various plotting submethods return a matplotlib axes object, so you can invert its y axis directly:
```py
ax = df.plot.barh()  # or df.plot(), or similar
ax.invert_yaxis()
```


Question:
Plot a bar plot from a Pandas DataFrame Assuming I have a DataFrame that looks like this:
```none
Hour  V1  V2  A1  A2
   0  15  13  25  37
   1  26  52  21  45
   2  18  45  45  25
   3  65  38  98  14
```
I'm trying to create a bar plot to compare columns V1 and V2 by the Hour. When I do:
```py
import matplotlib.pyplot as plt
ax = df.plot(kind='bar', title ="V comp",figsize=(15,10),legend=True, fontsize=12)
ax.set_xlabel("Hour",fontsize=12)
ax.set_ylabel("V",fontsize=12)
```
I get a plot and a legend with all the columns' values and names. How can I modify my code so the plot and legend only displays the columns V1 and V2?

Response:
To plot just a selection of your columns you can select the columns of interest by passing a list to the subscript operator:
```
ax = df[['V1','V2']].plot(kind='bar', title ="V comp", figsize=(15, 10), legend=True, fontsize=12)
```
What you tried was df['V1','V2'] this will raise a KeyError as correctly no column exists with that label, although it looks funny at first you have to consider that your are passing a list hence the double square brackets [[]].
```
import matplotlib.pyplot as plt
ax = df[['V1','V2']].plot(kind='bar', title ="V comp", figsize=(15, 10), legend=True, fontsize=12)
ax.set_xlabel("Hour", fontsize=12)
ax.set_ylabel("V", fontsize=12)
plt.show()
```


Question:
what does axes.flat in matplotlib do? I have seen various programs using matplotlib that uses the axes.flat function, like this code:
```
for i, ax in enumerate(axes.flat):
```
what does this do?

Response:
Let's look a minimal example, where we create some axes with plt.subplots, also see this question,
```
import matplotlib.pyplot as plt

fig, axes = plt.subplots(ncols=2,nrows=3, sharex=True, sharey=True)

for i, ax in enumerate(axes.flat):
    ax.scatter([i//2+1, i],[i,i//3])

plt.show()
```
Here, axes is a numpy array of axes,
```
print(type(axes))
> <type 'numpy.ndarray'>
print(axes.shape)
> (3L, 2L)
```
axes.flat is not a function, it's an attribute of the numpy.ndarray: numpy.ndarray.flat ndarray.flat A 1-D iterator over the array. This is a numpy.flatiter instance, which acts similarly to, but is not a subclass of, Python’s built-in iterator object. Example:
```
import numpy as np

a = np.array([[2,3],
              [4,5],
              [6,7]])

for i in a.flat:
    print(i)
```
which would print the numbers 2 3 4 5 6 7. Being an interator over the array, you can use it to loop over all the axes from the 3x2 array of axes,
```
for i, ax in enumerate(axes.flat):
```
For each iteration it would yield the next axes from that array, such that you may easily plot to all axes in a single loop. An alternative would be to use axes.flatten(), where flatten() is method of the numpy array. Instead of an iterator, it returns a flattened version of the array:
```
for i, ax in enumerate(axes.flatten()):
```
There is no difference seen from the outside between the two. However an iterator does not actually create a new array and may hence be slightly faster (although this will never be noticable in the case of matplotlib axes objects).
```
flat1 = [ax for ax in axes.flat]
flat2 = axes.flatten()
print(flat1 == flat2)
> [ True  True  True  True  True  True]
```
Iterating a flattened version of the axes array has the advantage that you will save one loop, compared to the naive approach of iterating over rows and columns separately,
```
for row in axes:
    for ax in row:
        ax.scatter(...)
```


Question: How to create a scatter plot legend with only one symbol for each label? How can I create a scatter plot legend without two symbols showing up each time? I can understand why you'd want this when you're joining symbols by lines, but for a pure scatter plot, all I want in the legend is one example of the symbol. This plot from a previous stackoverflow post shows the kind of thing I mean:

Response:
In the legend command you can use the scatterpoints option:
```
ax.legend(loc=0, scatterpoints = 1)
```
For a normal plot, it is the option numpoints. Here you can find more information about the keyword arguments for the legend: http://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.legend


Question:
Labels for clustermap in seaborn I have several questions about labeling for clustermap in seaborn. First is it possible to extract the the distance values for the hierarchical clustering, and plot the value on the tree structure visualization (maybe only the first three levels). Here is my example code for creating a clustermap plot:
```
import pandas as pd
import numpy as np
import seaborn as sns
get_ipython().magic(u'matplotlib inline')

m = np.random.rand(50, 50)
df = pd.DataFrame(m, columns=range(4123, 4173), index=range(4123, 4173))
sns.clustermap(df, metric="correlation")
```
The other two questions are: - How to rotate the y labels since they overlaps together. - How to move the color bar to the bottom or right. (There was a question for heatmap, but does not work for my case. Also does not address the color bar position)

Response:
I had the exact same issue with the labels on the y-axis being rotated and found a solution. The issue is that if you do plt.yticks(rotation=0) like suggested in the question you referenced, it will rotate the labels on your colobar due to the way ClusterGrid works. To solve it and rotate the right labels, you need to reference the Axes from the underlying Heatmap and rotate these:
```
cg = sns.clustermap(df, metric="correlation")
plt.setp(cg.ax_heatmap.yaxis.get_majorticklabels(), rotation=0)
```
For your other question about the colorbar placement, I don't think this is supported at the moment, as indicated by this Github issue unfortunately. And finally for the hierarchical clustering distance values, you can access the linkage matrics for rows or columns with:
```
cg = sns.clustermap(df, metric="correlation")
cg.dendrogram_col.linkage # linkage matrix for columns
cg.dendrogram_row.linkage # linkage matrix for rows
```


Question:
How to set my xlabel at the end of xaxis I want my x axis has the label like this format
```
0 1 2 3 4 5 Xlabel
```
but I try code below it result me in 2 lines
```
self.axes.set_xticks(np.arange(0,6,1))
self.axes.set_xlabel('Xlabel', fontsize=9,x=1,y=1)
```
=> my result :(
```
0 1 2 3 4 5
        Xlabel
```

Response:
When setting the xlabel, the x parameter assigns the position in axis units, so 0 is the origin and 1 is the right edge of the plot. y is ignored as it's expected to be a default value, just below the tick marks. To override this behavior, you can set the position in axis units using the Axis set_label_coords method. You can use other units by also providing a transform. Here is an example of this:
```
import matplotlib.pyplot as plt
import numpy as np

ax = plt.gca()
ax.set_xticks(np.arange(0,6,1))
label = ax.set_xlabel('Xlabel', fontsize = 9)
ax.xaxis.set_label_coords(1.05, -0.025)

plt.savefig('labelAtEnd.png')
plt.show()
```
Resulting in: The x value (1.05) was chosen to position the label outside the Axes frame. The y value (-0.025) was chose as a best guess to the position you desired. Using a transform, it might be possible to automatically position the text in line with the Tick labels. EDIT: Here's an extended example using a transform. It is not necissarily more helpful to use the last ticklabel's transform, because it does not take into account the size of the text and how it is aligned. So to get a somewhat desired effect, I had to 1) use the same font size for my x label, 2) position the vertical alignment (va) to 'top', and 3) position the horizontal alignment to 'left'. The transform for each tick is set for data units for x (because it's an xaxis) and axis units for y (0 to 1), but displaced by a fixed padding (in pixels) from the x axis.
```
import matplotlib.pyplot as plt
import numpy as np

ax = plt.gca()
ax.set_xticks(np.arange(0,6,1))
ax.set_yticks(np.arange(0,6,1))
label = ax.set_xlabel('xlabel', ha='left', va = 'top', )#fontsize = 9)

# need to draw the figure first to position the tick labels
fig = plt.gcf()
fig.draw(fig.canvas.get_renderer())

# get a tick and will position things next to the last one
ticklab = ax.xaxis.get_ticklabels()[0]
trans = ticklab.get_transform()
ax.xaxis.set_label_coords(5.1, 0, transform=trans)

plt.savefig('labelAtEnd2.png')
plt.show()
```
This results in:


Question: How to show an AxesSubplot in Python? I have an object fig2 that is a class mathplotlib.axes.axessubplot, but when I try to execute fig2.show(), python says axessubplot object has no attribute show. How can I show AxesSubplot?

Response:
You should call matplotlib.pyplot.show(), which is a method that displays all the figures. If you have imported as plt, then:
```
import matplotlib.pyplot as plt

# create fig1 (of type plt.figure)
# create fig2

plt.show()  # will display fig1 and fig2 in different windows
```


Question:
Matplotlib imshow() stretch to "fit width" I've got an image, and a measure associated with each column of its pixels. I'm using pyplot to create a figure with the image on top, and a plot of the column measurements below. I'm using something like this:
```
import numpy as np
import matplotlib.pyplot as plt

A = np.random.rand(34*52).reshape(34,52)
means = np.average(A,axis=0)

plt.figure()

plt.subplot(2,1,1)
plt.imshow(A, interpolation='nearest' )

plt.subplot(2,1,2)
plt.plot(means)

plt.show()
```
How can I stretch the image's width to the match that of the plots. That way, when looking at the measurements in the plot, the souce pixels will be in a column directly above it.

Response:
Turns out that it's as simple as giving aspect='auto' to the imshow call.
```
plt.imshow(A, interpolation='nearest', aspect='auto')
```


Question: Different colors for points and line in Seaborn regplot All examples listed in Seaborn's regplot documentation show the same color for dots and the regression line. Changing the color argument changes both. How can one set a different color for the points as the line?

Response:
You are right in that the color argument changes all the plot elements. However, if you read the last bit of the relevant sentence in the documentation: color : matplotlib color Color to apply to all plot elements; will be superseded by colors passed in scatter_kws or line_kws. Therefore, using scatter_kws or line_kws we can change the color of them individually. Taking the first example given in the documentation:
```
import seaborn as sns

tips = sns.load_dataset("tips")
ax = sns.regplot(x="total_bill", y="tip", data=tips,
                 scatter_kws={"color": "black"}, line_kws={"color": "red"})

plt.show()
```
Gives:


Question:
how to plot and annotate hierarchical clustering dendrograms in scipy/matplotlib I'm using dendrogram from scipy to plot hierarchical clustering using matplotlib as follows:
```
mat = array([[1, 0.5, 0.9],
             [0.5, 1, -0.5],
             [0.9, -0.5, 1]])
plt.subplot(1,2,1)
plt.title("mat")
dist_mat = mat
linkage_matrix = linkage(dist_mat,
                         "single")
print "linkage2:"
print linkage(1-dist_mat, "single")
dendrogram(linkage_matrix,
           color_threshold=1,
           labels=["a", "b", "c"],
           show_leaf_counts=True)
plt.subplot(1,2,2)
plt.title("1 - mat")
dist_mat = 1 - mat
linkage_matrix = linkage(dist_mat,
                         "single")
dendrogram(linkage_matrix,
           color_threshold=1,
           labels=["a", "b", "c"],
           show_leaf_counts=True)
```
My questions are: first, why does mat and 1-mat give identical clusterings here? and second, how can I annotate the distance along each branch of the tree using dendrogram so that the distances between pairs of nodes can be compared? finally it seems that show_leaf_counts flag is ignored, is there a way to turn it on so that the number of objects in each class is shown? thanks.

Response:
The input to linkage() is either an n x m array, representing n points in m-dimensional space, or a one-dimensional array containing the condensed distance matrix. In your example, mat is 3 x 3, so you are clustering three 3-d points. Clustering is based on the distance between these points. Why does mat and 1-mat give identical clusterings here? The arrays mat and 1-mat produce the same clustering because the clustering is based on distances between the points, and neither a reflection (-mat) nor a translation (mat + offset) of the entire data set change the relative distances between the points. How can I annotate the distance along each branch of the tree using dendrogram so that the distances between pairs of nodes can be compared? In the code below, I show how you can use the data returned by dendrogram to label the horizontal segments of the diagram with the corresponding distance. The values associated with the keys icoord and dcoord give the x and y coordinates of each three-segment inverted-U of the figure. In augmented_dendrogram this data is used to add a label of the distance (i.e. y value) of each horizontal line segment in dendrogram.
```
from scipy.cluster.hierarchy import dendrogram
import matplotlib.pyplot as plt

def augmented_dendrogram(*args, **kwargs):

    ddata = dendrogram(*args, **kwargs)

    if not kwargs.get('no_plot', False):
        for i, d in zip(ddata['icoord'], ddata['dcoord']):
            x = 0.5 * sum(i[1:3])
            y = d[1]
            plt.plot(x, y, 'ro')
            plt.annotate("%.3g" % y, (x, y), xytext=(0, -8),
                         textcoords='offset points',
                         va='top', ha='center')

    return ddata
```
For your mat array, the augmented dendrogram is So point 'a' and 'c' are 1.01 units apart, and point 'b' is 1.57 units from the cluster ['a', 'c']. It seems that show_leaf_counts flag is ignored, is there a way to turn it on so that the number of objects in each class is shown? The flag show_leaf_counts only applies when not all the original data points are shown as leaves. For example, when trunc_mode = "lastp", only the last p nodes are show. Here's an example with 100 points:
```
import numpy as np
from scipy.cluster.hierarchy import linkage
import matplotlib.pyplot as plt
from augmented_dendrogram import augmented_dendrogram

# Generate a random sample of `n` points in 2-d.
np.random.seed(12312)
n = 100
x = np.random.multivariate_normal([0, 0], np.array([[4.0, 2.5], [2.5, 1.4]]),
                                  size=(n,))

plt.figure(1, figsize=(6, 5))
plt.clf()
plt.scatter(x[:, 0], x[:, 1])
plt.axis('equal')
plt.grid(True)

linkage_matrix = linkage(x, "single")

plt.figure(2, figsize=(10, 4))
plt.clf()

plt.subplot(1, 2, 1)
show_leaf_counts = False
ddata = augmented_dendrogram(linkage_matrix,
               color_threshold=1,
               p=6,
               truncate_mode='lastp',
               show_leaf_counts=show_leaf_counts,
               )
plt.title("show_leaf_counts = %s" % show_leaf_counts)

plt.subplot(1, 2, 2)
show_leaf_counts = True
ddata = augmented_dendrogram(linkage_matrix,
               color_threshold=1,
               p=6,
               truncate_mode='lastp',
               show_leaf_counts=show_leaf_counts,
               )
plt.title("show_leaf_counts = %s" % show_leaf_counts)

plt.show()
```
These are the points in the data set: With p=6 and trunc_mode="lastp", dendrogram only shows the "top" of the dendrogram. The following shows the effect of show_leaf_counts.


Question:
How to get default blue colour of matplotlib.pyplot.scatter? How do I get the shade of blue that is used as default in matplotlib.pyplot.scatter? When giving the keyword argument c='b', it gives a darker shade of blue. In this documentation of matplotlib.pyplot.scatter, it says the default is supposed to be 'b', yet it looks different. See example below:
```
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.scatter(-1, 0)
ax.text(-1, 0, 'Default blue')
ax.scatter(1, 0, c='b')
ax.text(1, 0, 'Darker blue')
ax.set_xlim(-2, 2)
```
I'm using Python 3.5 with Matplotlib 2.0.0. The reason why I'm asking this, is because I would like to use the same blue colour when plotting some of the points one by one with plt.plot().

Response:
The default colour cycle was changed in matplotlib version 2 as shown in the docs. Therefore, to plot the "new" default blue you can do 2 things:
```
fig, ax = plt.subplots()

ax.scatter(-1, 1)
ax.text(-0.9, 1, 'Default blue')

ax.scatter(1, 1, c='#1f77b4')
ax.text(1.1, 1, 'Using hex value')

ax.scatter(0, 0.5, c='C0')
ax.text(0.1, 0.5, 'Using "C0" notation')

ax.set_xlim(-2, 3)
ax.set_ylim(-1,2)
plt.show()
```
Which gives: Alternatively you can change the colour cycle back to what it was:
```
import matplotlib as mpl
from cycler import cycler

mpl.rcParams['axes.prop_cycle'] = cycler(color='bgrcmyk')
```


Question: How do I show logarithmically spaced grid lines at all ticks on a log-log plot using Matplotlib? I'm trying to plot a log-log graph that shows logarithmically spaced grid lines at all of the ticks that you see along the bottom and left hand side of the plot. I've been able to show some gridlines by using matplotlib.pyplot.grid(True), but this is only showing grid lines for me at power of 10 intervals. So as an example, here is what I'm currently getting: I'd really like something with grid lines looking more like this, where the gridlines aren't all evenly spaced: How would I go about achieving this in Matplotlib?

Response:
Basically, you just need to put in the parameter which="both" in the grid command so that it becomes:
```
matplotlib.pyplot.grid(True, which="both")
```
Other options for which are 'minor' and 'major' which are the major ticks (which are shown in your graph) and the minor ticks which you are missing. If you want solid lines then you can use ls="-" as a parameter to grid() as well. Here is an example for kicks:
```
import numpy as np
from matplotlib import pyplot as plt

x = np.arange(0, 100, .5)
y = 2 * x**3

plt.loglog(x, y)
plt.grid(True, which="both", ls="-")
plt.show()
```
which generates: More details on the Matplotlib Docs


Question: Axes class - set explicitly size (width/height) of axes in given units I want to to create a figure using matplotlib where I can explicitly specify the size of the axes, i.e. I want to set the width and height of the axes bbox. I have looked around all over and I cannot find a solution for this. What I typically find is how to adjust the size of the complete Figure (including ticks and labels), for example using fig, ax = plt.subplots(figsize=(w, h)) This is very important for me as I want to have a 1:1 scale of the axes, i.e. 1 unit in paper is equal to 1 unit in reality. For example, if xrange is 0 to 10 with major tick = 1 and x axis is 10cm, then 1 major tick = 1cm. I will save this figure as pdf to import it to a latex document. This question brought up a similar topic but the answer does not solve my problem (using plt.gca().set_aspect('equal', adjustable='box') code) From this other question I see that it is possible to get the axes size, but not how to modify them explicitly. Any ideas how I can set the axes box size and not just the figure size. The figure size should adapt to the axes size. Thanks! For those familiar with pgfplots in latex, it will like to have something similar to the scale only axis option (see here for example).

Response:
The axes size is determined by the figure size and the figure spacings, which can be set using figure.subplots_adjust(). In reverse this means that you can set the axes size by setting the figure size taking into acount the figure spacings:
```
import matplotlib.pyplot as plt

def set_size(w,h, ax=None):
    """ w, h: width, height in inches """
    if not ax: ax=plt.gca()
    l = ax.figure.subplotpars.left
    r = ax.figure.subplotpars.right
    t = ax.figure.subplotpars.top
    b = ax.figure.subplotpars.bottom
    figw = float(w)/(r-l)
    figh = float(h)/(t-b)
    ax.figure.set_size_inches(figw, figh)

fig, ax=plt.subplots()

ax.plot([1,3,2])

set_size(5,5)

plt.show()
```


Question:
How to increase the font size of the legend in seaborn I have the following codes to create a Seaborn strip plot. I am having a hard time figuring out how to increase the font size of the legend appearing in the plot.
```py
g=sns.stripplot(x="Market", y="Rate", hue="Group",data=myBenchmarkData, jitter=True, size=12, alpha=0.5)
g.axes.set_title("4* Rate Market and by Hotel Groups for Year 2016",fontsize=25)
g.set_xlabel("Market",fontsize=20)
g.set_ylabel("Rate (in EUR)",fontsize=20)
g.tick_params(labelsize=15)
plt.savefig ('benchmark1.png')
```
I am OK with my x-axis and y-axis labels font size but the font size of the legend in my plot is small. How to change it?

Response:
Use matplotlib function setp according to this example:
```
import seaborn as sns
import matplotlib.pylab as plt
sns.set_style("whitegrid")
tips = sns.load_dataset("tips")

ax = sns.stripplot(x="sex", y="total_bill", hue="day", data=tips, jitter=True)
plt.setp(ax.get_legend().get_texts(), fontsize='22') # for legend text
plt.setp(ax.get_legend().get_title(), fontsize='32') # for legend title

plt.show()
```
Another way is to change font_scale of all graph with plotting_context: http://seaborn.pydata.org/generated/seaborn.plotting_context.html


Question: How to add title and xlabel and ylabel Is there a way to add title (and xlabel and ylabel) to plt.scatter(x,y,...) or plt.plot(x,y,...) directly without writing additional lines? It is easy to add it when we use Series_name.plot in which we simply write Series_name.plot(...,title='name') but it does not work for me if I write: plt.scatter(...,title='name') or plt.plot(...,title='name') [plt<< import matplotlib.pyplot as plt] I am using Python 3.

Response:
From the documentation of plt.scatter() there is no such arguments to set the title or labels. But neither does the plt.plot() command have such arguments. plt.plot(x,y, title="title") throws an error AttributeError: Unknown property title. So I wonder why this should work in either case. In any case, the usual way to set the title is plt.title. The usual way to set the labels is plt.xlabeland plt.ylabel.
```
import matplotlib.pyplot as plt

x= [8,3,5]; y = [3,4,5]
plt.scatter(x,y)
plt.title("title")
plt.xlabel("x-label")
plt.ylabel("y-label")
plt.show()
```


Question: Seaborn heatmap not displaying all xticks and yticks I have a pandas dataframe of shape (39, 67). When I plot it's seaborn heatmap, I don't get as many labels on the X and Y axes. .get_xticklabels() method also returns only 23 labels. matplotlib doesn't show any labels (only numbers) as well. Both these heatmaps are for the same dataframe (39, 67).

Response:
To ensure the labels are visible, you have to set the parameters xticklabels, yticklabels to True, like so.
```
import seaborn as sns
sns.heatmap(dataframe, xticklabels=True, yticklabels=True)
```
Here's the documentation for the heatmap function.