Question:
Python NetworkX -- set node color automatically based on number of attribute options I am using NetworkX to analyze and visualize social networks. Often, the nodes within the network have attribute information associated with them, such as division. However, I do not always know how many options there might be for the attribute division. For example, sometimes there might be only 3 divisions represented as node attributes within the network, other times there might be 30 divisions. I've figured out how to set node colors based on node attributes (see code below). However, in this example, I knew how different options there were for the node attribute group (5 options), and set each color automatically. When there are only 3 or 5 options for node attributes, it's not difficult to pick the node attribute colors, but this becomes unrealistic when there are many more options. What I would like to figure out is how can I automatically pick the optimal node attribute colors based on the number of node attribute options provided. Sometime I have have 5 options for the attribute to color by, other times I might have 30 options for the node attribute to color by, and I don't want to set each node color individually. I'm not sure if this is something that I should be able to do with the colormap function, or if that is only for color nodes by numeric measures such as degree centrality. NETWORKX CODE
```
import networkx as nx

pylab inline

# create an empty graph
g = nx.Graph()

# open csv edgelist and read edges into graph
for line in open('phils_network_edgelist.csv', 'rb'):
    edge = line.rstrip().split(',')
    g.add_edge(edge[0], edge[1])

# draw network without node color
nx.draw(g, with_labels=False, node_size=25)
```
```
# read in node attributes as list of tuples
group_attr = []
for line in open('phils_network_attribute_group.csv', 'rb'):
    group_attr.append(tuple(line.rstrip().split(',')))

# convert list of tuples into a dict
group_attr_dict = dict(set(sorted(group_attr)))

# set nodes attributes
nx.set_node_attributes(g, "group", group_attr_dict)

# create empty list for node colors
node_color = []

# for each node in the graph
for node in g.nodes(data=True):

    # if the node has the attribute group1
    if 'group1' in node[1]['group']:
        node_color.append('blue')

    # if the node has the attribute group1
    elif 'group2' in node[1]['group']:
        node_color.append('red')

    # if the node has the attribute group1
    elif 'group3' in node[1]['group']:
        node_color.append('green')

    # if the node has the attribute group1
    elif 'group4' in node[1]['group']:
        node_color.append('yellow')

    # if the node has the attribute group1
    elif 'group5' in node[1]['group']:
        node_color.append('orange')

# draw graph with node attribute color
nx.draw(g, with_labels=False, node_size=25, node_color=node_color)
```
NETWORK DATA
```

```python
g.nodes(data=True)
#Output
#[('BD', {'group': 'group5'}),
# ('WC', {'group': 'group3'}),
# ('BA', {'group': 'group4'}),
# ('WM', {'group': 'group3'}),
# ('JR', {'group': 'group1'}),
# ('JS', {'group': 'group3'}),
# ('JL', {'group': 'group4'}),
# ('JM', {'group': 'group2'}),
# ('JK', {'group': 'group2'}),
# ('JF', {'group': 'group2'}),
# ('JG', {'group': 'group2'}),
# ('JA', {'group': 'group2'}),
# ('JB', {'group': 'group4'}),
# ('JC', {'group': 'group4'}),
# ('RR', {'group': 'group3'}),
# ('RS', {'group': 'group3'}),
# ('TTI', {'group': 'group3'}),
# ('RB', {'group': 'group1'}),
# ('RL', {'group': 'group3'}),
# ('RO', {'group': 'group4'}),
# ('LHA', {'group': 'group2'}),
# ('LHI', {'group': 'group1'}),
# ('GF', {'group': 'group2'}),
# ('GB', {'group': 'group4'}),
# ('EM', {'group': 'group2'}),
# ('HR', {'group': 'group5'}),
# ('BS', {'group': 'group3'}),
# ('HH', {'group': 'group4'}),
# ('HA', {'group': 'group1'}),
# ('PS', {'group': 'group1'}),
# ('PW', {'group': 'group1'}),
# ('PB', {'group': 'group1'}),
# ('PC', {'group': 'group5'}),
# ('MFR', {'group': 'group4'}),
# ('JMA', {'group': 'group5'}),
# ('PN', {'group': 'group4'}),
# ('PL', {'group': 'group3'}),
# ('ZL', {'group': 'group4'}),
# ('EB', {'group': 'group2'}),
# ('ET', {'group': 'group3'}),
# ('EW', {'group': 'group1'}),
# ('ER', {'group': 'group3'}),
# ('MF', {'group': 'group3'}),
# ('MA', {'group': 'group4'}),
# ('MM', {'group': 'group2'}),
# ('MN', {'group': 'group4'}),
# ('MH', {'group': 'group3'}),
# ('MK', {'group': 'group2'}),
# ('JLA', {'group': 'group2'}),
# ('MP', {'group': 'group1'}),
# ('MS', {'group': 'group4'}),
# ('MR', {'group': 'group4'}),
# ('FI', {'group': 'group5'}),
# ('CJ', {'group': 'group4'}),
# ('CO', {'group': 'group5'}),
# ('CM', {'group': 'group4'}),
# ('CB', {'group': 'group2'}),
# ('CG', {'group': 'group2'}),
# ('CF', {'group': 'group5'}),
# ('CD', {'group': 'group3'}),
# ('CS', {'group': 'group2'}),
# ('CP', {'group': 'group2'}),
# ('CV', {'group': 'group2'}),
# ('KC', {'group': 'group1'}),
# ('KB', {'group': 'group3'}),
# ('SY', {'group': 'group2'}),
# ('KF', {'group': 'group2'}),
# ('KD', {'group': 'group3'}),
# ('KH', {'group': 'group1'}),
# ('SW', {'group': 'group1'}),
# ('KL', {'group': 'group2'}),
# ('KP', {'group': 'group3'}),
# ('KW', {'group': 'group1'}),
# ('SM', {'group': 'group2'}),
# ('SB', {'group': 'group4'}),
# ('DJ', {'group': 'group2'}),
# ('DD', {'group': 'group2'}),
# ('DV', {'group': 'group5'}),
# ('BJ', {'group': 'group3'}),
# ('DR', {'group': 'group2'}),
# ('KWI', {'group': 'group4'}),
# ('TW', {'group': 'group2'}),
# ('TT', {'group': 'group2'}),
# ('LH', {'group': 'group3'}),
# ('LW', {'group': 'group3'}),
# ('TM', {'group': 'group3'}),
# ('LS', {'group': 'group3'}),
# ('LP', {'group': 'group2'}),
# ('TG', {'group': 'group3'}),
# ('JCU', {'group': 'group2'}),
# ('AL', {'group': 'group1'}),
# ('AP', {'group': 'group3'}),
# ('AS', {'group': 'group3'}),
# ('IM', {'group': 'group4'}),
# ('AW', {'group': 'group3'}),
# ('HHI', {'group': 'group1'})]
```

```python
g.edges(data=True)
#Output
#[('BD', 'ZL', {}),
# ('BD', 'JCU', {}),
# ('BD', 'DJ', {}),
# ('BD', 'BA', {}),
# ('BD', 'CB', {}),
# ('BD', 'CG', {}),
# ('BD', 'AS', {}),
# ('BD', 'MH', {}),
# ('BD', 'AP', {}),
# ('BD', 'HH', {}),
# ('BD', 'TM', {}),
# ('BD', 'CF', {}),
# ('BD', 'CP', {}),
# ('BD', 'DR', {}),
# ('BD', 'CV', {}),
# ('BD', 'EB', {}),
# ('WC', 'JCU', {}),
# ('WC', 'JS', {}),
# ('BA', 'JR', {}),
# ('BA', 'JB', {}),
# ('BA', 'RR', {}),
# ('BA', 'RS', {}),
# ('BA', 'LH', {}),
# ('BA', 'PC', {}),
# ('BA', 'TTI', {}),
# ('BA', 'PL', {}),
# ('BA', 'JCU', {}),
# ('BA', 'CF', {}),
# ('BA', 'EB', {}),
# ('BA', 'GF', {}),
# ('BA', 'AS', {}),
# ('BA', 'IM', {}),
# ('BA', 'BJ', {}),
# ('BA', 'CS', {}),
# ('BA', 'KH', {}),
# ('BA', 'SW', {}),
# ('BA', 'MH', {}),
# ('BA', 'MR', {}),
# ('BA', 'HHI', {}),
# ('WM', 'EM', {}),
# ('WM', 'JCU', {}),
# ('WM', 'CO', {}),
# ('WM', 'LP', {}),
# ('WM', 'AW', {}),
# ('WM', 'KD', {}),
# ('WM', 'TT', {}),
# ('WM', 'JS', {}),
# ('WM', 'PB', {}),
# ('WM', 'JM', {}),
# ('WM', 'MFR', {}),
# ('WM', 'RB', {}),
# ('WM', 'MR', {}),
# ('WM', 'DV', {}),
# ('WM', 'TG', {}),
# ('WM', 'JF', {}),
# ('WM', 'JMA', {}),
# ('WM', 'FI', {}),
# ('WM', 'JB', {}),
# ('JR', 'GF', {}),
# ('JR', 'MFR', {}),
# ('JR', 'KH', {}),
# ('JR', 'JB', {}),
# ('JS', 'EM', {}),
# ('JS', 'PS', {}),
# ('JS', 'MF', {}),
# ('JS', 'JCU', {}),
# ('JS', 'KD', {}),
# ('JS', 'MH', {}),
# ('JS', 'TTI', {}),
# ('JS', 'RB', {}),
# ('JS', 'TG', {}),
# ('JL', 'KB', {}),
# ('JL', 'MN', {}),
# ('JL', 'LW', {}),
# ('JL', 'CS', {}),
# ('JL', 'ET', {}),
# ('JL', 'ER', {}),
# ('JM', 'EM', {}),
# ('JM', 'PS', {}),
# ('JM', 'KD', {}),
# ('JM', 'CD', {}),
# ('JM', 'JK', {}),
# ('JM', 'TG', {}),
# ('JM', 'RO', {}),
# ('JM', 'CV', {}),
# ('JK', 'HR', {}),
# ('JK', 'PS', {}),
# ('JF', 'EM', {}),
# ('JF', 'PS', {}),
# ('JF', 'LP', {}),
# ('JF', 'LHA', {}),
# ('JF', 'CD', {}),
# ('JF', 'RB', {}),
# ('JF', 'JG', {}),
# ('JF', 'KF', {}),
# ('JG', 'CJ', {}),
# ('JG', 'SY', {}),
# ('JG', 'KF', {}),
# ('JG', 'LHA', {}),
# ('JG', 'CD', {}),
# ('JG', 'RB', {}),
# ('JG', 'BS', {}),
# ('JA', 'CS', {}),
# ('JB', 'KC', {}),
# ('JB', 'JCU', {}),
# ('JB', 'MA', {}),
# ('JB', 'AW', {}),
# ('JB', 'KWI', {}),
# ('JB', 'KH', {}),
# ('JB', 'CF', {}),
# ('JB', 'EB', {}),
# ('JB', 'PB', {}),
# ('JB', 'MFR', {}),
# ('JB', 'KW', {}),
# ('JB', 'RB', {}),
# ('JB', 'MR', {}),
# ('JB', 'RL', {}),
# ('JB', 'FI', {}),
# ('JB', 'JMA', {}),
# ('JC', 'SM', {}),
# ('RR', 'MS', {}),
# ('RR', 'SW', {}),
# ('RR', 'LH', {}),
# ('RS', 'LH', {}),
# ('TTI', 'JCU', {}),
# ('TTI', 'SW', {}),
# ('TTI', 'CF', {}),
# ('RB', 'EM', {}),
# ('RB', 'PS', {}),
# ('RB', 'SY', {}),
# ('RB', 'JCU', {}),
# ('RB', 'KD', {}),
# ('RB', 'CF', {}),
# ('RB', 'LHI', {}),
# ('RB', 'CD', {}),
# ('RB', 'MH', {}),
# ('RB', 'CJ', {}),
# ('RB', 'TG', {}),
# ('RB', 'EB', {}),
# ('RO', 'PS', {}),
# ('LHA', 'CJ', {}),
# ('LHA', 'SY', {}),
# ('LHA', 'KF', {}),
# ('LHA', 'CD', {}),
# ('LHI', 'PS', {}),
# ('LHI', 'CJ', {}),
# ('GF', 'KC', {}),
# ('GF', 'MA', {}),
# ('GB', 'HR', {}),
# ('GB', 'MM', {}),
# ('GB', 'LS', {}),
# ('EM', 'LP', {}),
# ('EM', 'DV', {}),
# ('EM', 'TG', {}),
# ('HR', 'MM', {}),
# ('HR', 'MH', {}),
# ('HR', 'EB', {}),
# ('HR', 'LS', {}),
# ('BS', 'CD', {}),
# ('HH', 'ZL', {}),
# ('HH', 'CB', {}),
# ('HH', 'CP', {}),
# ('HH', 'DR', {}),
# ('HH', 'CV', {}),
# ('HA', 'SM', {}),
# ('PS', 'KD', {}),
# ('PS', 'CF', {}),
# ('PS', 'TG', {}),
# ('PW', 'CM', {}),
# ('PW', 'TW', {}),
# ('PW', 'TT', {}),
# ('PW', 'MH', {}),
# ('PW', 'AL', {}),
# ('PW', 'MP', {}),
# ('PW', 'CS', {}),
# ('PW', 'HHI', {}),
# ('PW', 'EW', {}),
# ('PB', 'CO', {}),
# ('PB', 'KH', {}),
# ('PB', 'CF', {}),
# ('PB', 'MFR', {}),
# ('PB', 'AW', {}),
# ('PB', 'MA', {}),
# ('PC', 'CS', {}),
# ('PC', 'JCU', {}),
# ('PC', 'SW', {}),
# ('MFR', 'KC', {}),
# ('MFR', 'JCU', {}),
# ('MFR', 'KH', {}),
# ('MFR', 'MH', {}),
# ('MFR', 'MR', {}),
# ('JMA', 'KWI', {}),
# ('JMA', 'AW', {}),
# ('PN', 'SB', {}),
# ('PL', 'HHI', {}),
# ('PL', 'MK', {}),
# ('PL', 'LH', {}),
# ('ZL', 'CB', {}),
# ('ZL', 'AP', {}),
# ('ZL', 'CP', {}),
# ('ZL', 'DR', {}),
# ('ZL', 'CV', {}),
# ('EB', 'JCU', {}),
# ('EB', 'DJ', {}),
# ('EB', 'CM', {}),
# ('EB', 'SW', {}),
# ('EB', 'MM', {}),
# ('EB', 'LS', {}),
# ('EB', 'CS', {}),
# ('EB', 'CP', {}),
# ('EB', 'CV', {}),
# ('ET', 'LW', {}),
# ('ET', 'ER', {}),
# ('ET', 'KB', {}),
# ('EW', 'TW', {}),
# ('EW', 'TT', {}),
# ('EW', 'HHI', {}),
# ('EW', 'AL', {}),
# ('ER', 'LW', {}),
# ('ER', 'KB', {}),
# ('MA', 'KW', {}),
# ('MA', 'AW', {}),
# ('MA', 'MR', {}),
# ('MM', 'LS', {}),
# ('MH', 'JCU', {}),
# ('MH', 'SY', {}),
# ('MH', 'DJ', {}),
# ('MH', 'CM', {}),
# ('MH', 'AL', {}),
# ('MH', 'SW', {}),
# ('MH', 'CF', {}),
# ('MH', 'LS', {}),
# ('MH', 'CS', {}),
# ('MH', 'TG', {}),
# ('MH', 'CP', {}),
# ('MH', 'CV', {}),
# ('MK', 'LH', {}),
# ('MK', 'KL', {}),
# ('MK', 'JLA', {}),
# ('MK', 'MS', {}),
# ('MK', 'CS', {}),
# ('JLA', 'CM', {}),
# ('JLA', 'KL', {}),
# ('JLA', 'MS', {}),
# ('JLA', 'CS', {}),
# ('JLA', 'SB', {}),
# ('JLA', 'HHI', {}),
# ('MP', 'TW', {}),
# ('MP', 'TT', {}),
# ('MP', 'HHI', {}),
# ('MS', 'CS', {}),
# ('MS', 'HHI', {}),
# ('FI', 'KW', {}),
# ('FI', 'AW', {}),
# ('FI', 'CF', {}),
# ('CJ', 'SY', {}),
# ('CJ', 'DD', {}),
# ('CJ', 'CD', {}),
# ('CO', 'AW', {}),
# ('CM', 'TW', {}),
# ('CM', 'TT', {}),
# ('CM', 'AL', {}),
# ('CM', 'CS', {}),
# ('CB', 'DJ', {}),
# ('CB', 'CP', {}),
# ('CB', 'CV', {}),
# ('CG', 'CF', {}),
# ('CF', 'JCU', {}),
# ('CF', 'AW', {}),
# ('CF', 'KH', {}),
# ('CF', 'LH', {}),
# ('CF', 'AP', {}),
# ('CF', 'AS', {}),
# ('CF', 'KW', {}),
# ('CF', 'CS', {}),
# ('CF', 'CV', {}),
# ('CD', 'SY', {}),
# ('CD', 'LP', {}),
# ('CD', 'KF', {}),
# ('CS', 'JCU', {}),
# ('CS', 'TW', {}),
# ('CS', 'TT', {}),
# ('CS', 'AS', {}),
# ('CS', 'LH', {}),
# ('CS', 'SB', {}),
# ('CS', 'HHI', {}),
# ('CP', 'DJ', {}),
# ('CP', 'AP', {}),
# ('CP', 'DR', {}),
# ('CP', 'CV', {}),
# ('CV', 'DJ', {}),
# ('CV', 'AP', {}),
# ('CV', 'DR', {}),
# ('KB', 'LW', {}),
# ('SY', 'KF', {}),
# ('KF', 'AP', {}),
# ('KD', 'TG', {}),
# ('SW', 'BJ', {}),
# ('SW', 'IM', {}),
# ('SW', 'LH', {}),
# ('KL', 'TT', {}),
# ('KP', 'TM', {}),
# ('KW', 'JCU', {}),
# ('SB', 'AL', {}),
# ('DJ', 'TG', {}),
# ('BJ', 'IM', {}),
# ('KWI', 'AW', {}),
# ('TW', 'TT', {}),
# ('TW', 'AL', {}),
# ('TW', 'HHI', {}),
# ('TT', 'AL', {}),
# ('TT', 'HHI', {}),
# ('LH', 'JCU', {}),
# ('JCU', 'AP', {}),
# ('JCU', 'AS', {}),
# ('AL', 'HHI', {})]
#```
```

Response:
Here is an example of how to use a colormap. It's a little tricky. If you want a customized discrete colormap you can try this SO answer Matplotlib discrete colorbar
```
import matplotlib.pyplot as plt
# create number for each group to allow use of colormap
from itertools import count
# get unique groups
groups = set(nx.get_node_attributes(g,'group').values())
mapping = dict(zip(sorted(groups),count()))
nodes = g.nodes()
colors = [mapping[g.nodes[n]['group']] for n in nodes]

# drawing nodes and edges separately so we can capture collection for colobar
pos = nx.spring_layout(g)
ec = nx.draw_networkx_edges(g, pos, alpha=0.2)
nc = nx.draw_networkx_nodes(g, pos, nodelist=nodes, node_color=colors, node_size=100, cmap=plt.cm.jet)
plt.colorbar(nc)
plt.axis('off')
plt.show()
```


Question:
Centering x-tick labels between tick marks in matplotlib I want to have the x-tick date labels centered between the tick marks, instead of centered about the tick marks as shown in the photo below. I have read the documentation but to no avail - does anyone know a way to do this? Here is everything that I've used for my x-axis tick formatting if it helps:
```
day_fmt = '%d'
myFmt = mdates.DateFormatter(day_fmt)
ax.xaxis.set_major_formatter(myFmt)
ax.xaxis.set_major_locator(matplotlib.dates.DayLocator(interval=1))

for tick in ax.xaxis.get_major_ticks():
    tick.tick1line.set_markersize(0)
    tick.tick2line.set_markersize(0)
    tick.label1.set_horizontalalignment('center')
```

Response:
One way to do it is to use the minor ticks. The idea is that you set the minor ticks so that they are located halfway between the major ticks, and you manually specify the labels. For example:
```
import matplotlib.ticker as ticker

# a is an axes object, e.g. from figure.get_axes()

# Hide major tick labels
a.xaxis.set_major_formatter(ticker.NullFormatter())

# Customize minor tick labels
a.xaxis.set_minor_locator(ticker.FixedLocator([1.5,2.5,3.5,4.5,5.5]))
a.xaxis.set_minor_formatter(ticker.FixedFormatter(['1','2','3','4','5']))
```
The three lines: "Hide" the 1,2,3,4,... that you have on the major ticks Set minor ticks halfway between the major ticks (assuming your major ticks are at 1,2,3...) Manually specifies the labels for the minor ticks. Here, '1' would be between 1.0 and 2.0 on the graph. This is just a simple example. You would probably want to streamline it a bit by populating the lists in a loop or something. You can also experiment with other locators or formatters. Edit: Alternatively, as suggested in the comments:
```
# Hide major tick labels
a.set_xticklabels('')

# Customize minor tick labels
a.set_xticks([1.5,2.5,3.5,4.5,5.5],      minor=True)
a.set_xticklabels(['1','2','3','4','5'], minor=True)
```
Example: Before: After:


Question:
The preferred way to set matplotlib figure/axes properties Say I have a matplotlib axes called ax, and I want to set several of its properties. Currently, I do it like this:
```
ax.set_yscale('log')
ax.set_xlim([0,10])
ax.set_xlabel('some label')
```
But it gets tedious after a while. Then I ran into this method:
```
ax.set(yscale='log', xlim=[0,10], xlabel='some label')
```
Much more concise, but it seems a bit undocumented. I mean all the documentation says is "A tkstyle set command, pass kwargs to set properties". What is the preferred or idiomatic way? Is the set method api stable?

Response: Pyplot tutorial appears to recommend ax.set_xxx() functions, but also mentions .setp(xxx=). On the other hand, .set(xxx=) function is not used and .setp(xxx=), while documented, is not used in any examples (Pyplot API). I understand it that matplotlib supports both imperative programming style and matlab-like style. Reason being the target user bases -- those already familiar with Python and those who used Matlab before. I conclude that matplotlib recommended api is .set_xxx(). A quick check through the gallery confirms this. Edit: it appears there are examples of both in the gallery now. Similar duality exists for keyword arguments to plot functions, except that imperative API is not that obvious.


Question:
Creating square subplots (of equal height and width) in matplotlib When I run this code
```
from pylab import *

figure()
ax1 = subplot(121)
plot([1, 2, 3], [1, 2, 3])
subplot(122, sharex=ax1, sharey=ax1)
plot([1, 2, 3], [1, 2, 3])
draw()
show()
```
I get two subplots which are "squished" in the X-dimension. How do I get these subplots such that the height of the Y-axis equals the width of the X-axis, for both subplots? I am using matplotlib v.0.99.1.2 on Ubuntu 10.04. Update 2010-07-08: Let's look at some things that don't work. After Googling around all day, I thought that it might be related to auto-scaling. So I tried fiddling with that.
```
from pylab import *

figure()
ax1 = subplot(121, autoscale_on=False)
plot([1, 2, 3], [1, 2, 3])
subplot(122, sharex=ax1, sharey=ax1)
plot([1, 2, 3], [1, 2, 3])
draw()
show()
```
matplotlib insists on auto-scaling.
```
from pylab import *

figure()
ax1 = subplot(121, autoscale_on=False)
plot([1, 2, 3], [1, 2, 3])
subplot(122, sharex=ax1, sharey=ax1, autoscale_on=False)
plot([1, 2, 3], [1, 2, 3])
draw()
show()
```
In this one, the data completely disappears. WTF, matplotlib? Just WTF? Okay, well maybe if we fix the aspect ratio?
```
from pylab import *

figure()
ax1 = subplot(121, autoscale_on=False)
plot([1, 2, 3], [1, 2, 3])
axes().set_aspect('equal')
subplot(122, sharex=ax1, sharey=ax1)
plot([1, 2, 3], [1, 2, 3])
draw()
show()
```
This one causes the first subplot to disappear entirely. That's hilarious! Who came up with that one? In all seriousness, now... should this really be such a hard thing to accomplish?

Response:
Your problem in setting the aspect of the plots is coming in when you're using sharex and sharey. One workaround is to just not used shared axes. For example, you could do this:
```
from pylab import *

figure()
subplot(121, aspect='equal')
plot([1, 2, 3], [1, 2, 3])
subplot(122, aspect='equal')
plot([1, 2, 3], [1, 2, 3])
show()
```
However, a better workaround is to change the "adjustable" keywarg... You want adjustable='box', but when you're using shared axes, it has to be adjustable='datalim' (and setting it back to 'box' gives an error). However, there's a third option for adjustable to handle exactly this case: adjustable="box-forced". For example:
```
from pylab import *

figure()
ax1 = subplot(121, aspect='equal', adjustable='box-forced')
plot([1, 2, 3], [1, 2, 3])
subplot(122, aspect='equal', adjustable='box-forced', sharex=ax1, sharey=ax1)
plot([1, 2, 3], [1, 2, 3])
show()
```
Or in more modern style (note: this part of the answer wouldn't have worked in 2010):
```
import matplotlib.pyplot as plt

fig, axes = plt.subplots(ncols=2, sharex=True, sharey=True)
for ax in axes:
    ax.plot([1, 2, 3], [1, 2, 3])
    ax.set(adjustable='box-forced', aspect='equal')

plt.show()
```
Either way, you'll get something similar to:


Question:
Plot all pandas dataframe columns separately I have a pandas dataframe who just has numeric columns, and I am trying to create a separate histogram for all the features
```
ind group people value value_50
 1      1    5    100    1
 1      2    2    90     1
 2      1    10   80     1
 2      2    20   40     0
 3      1    7    10     0
 3      2    23   30     0
```
but in my real life data there are 50+ columns, how can I create a separate plot for all of them I have tried
```
df.plot.hist( subplots = True, grid = True)
```
It gave me an overlapping unclear plot. how can I arrange them using pandas subplots = True. Below example can help me to get graphs in (2,2) grid for four columns. But its a long method for all 50 columns
```
fig, [(ax1,ax2),(ax3,ax4)]  = plt.subplots(2,2, figsize = (20,10))
```

Response:
Pandas subplots=True will arange the axes in a single column.
```
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

df = pd.DataFrame(np.random.rand(7,20))

df.plot(subplots=True)

plt.tight_layout()
plt.show()
```
Here, tight_layout isn't applied, because the figure is too small to arange the axes nicely. One can use a bigger figure (figsize=(...)) though. In order to have the axes on a grid, one can use the layout parameter, e.g.
```
df.plot(subplots=True, layout=(4,5))
```
The same can be achieved if creating the axes via plt.subplots()
```
fig, axes = plt.subplots(nrows=4, ncols=5)
df.plot(subplots=True, ax=axes)
```


Question:
How to write text above the bars on a bar plot (Python)? I have this graph: I want to write the count above each column. These values are in the first and second lists. Can you help me solve this problem? I tried something without success. This is the code for the graph:
```
countListFast = [1492.0, 497.0, 441.0, 218.0, 101.0, 78.0, 103.0]
countListSlow = [1718.0, 806.0, 850.0, 397.0, 182.0, 125.0, 106.0]

errorRateListOfFast = ['9.09', '9.09', '9.38', '9.40', '7.89', '8.02', '10.00']
errorRateListOfSlow = ['10.00', '13.04', '14.29', '12.50', '14.29', '14.53', '11.11']

opacity = 0.4
bar_width = 0.35

plt.xlabel('Tasks')
plt.ylabel('Error Rate')
plt.xticks(range(len(errorRateListOfFast)),('[10-20)', '[20-30)', '[30-50)', '[50-70)','[70-90)', '[90-120)', ' [120 < )'), rotation=30)
plt.bar(np.arange(len(errorRateListOfFast))+ bar_width, errorRateListOfFast, bar_width, align='center', alpha=opacity, color='b', label='Fast <= 6 sec.')
plt.bar(range(len(errorRateListOfSlow)), errorRateListOfSlow, bar_width, align='center', alpha=opacity, color='r', label='Slower > 6 sec.')
plt.legend()
plt.tight_layout()
plt.show()
```

Response:
plt.bar() returns a list of rectangles that can be used to position suitable text above each of the bars as follows:
```
import matplotlib.pyplot as plt
import numpy as np

errorRateListOfFast = ['9.09', '9.09', '9.38', '9.40', '7.89', '8.02', '10.00']
errorRateListOfSlow = ['10.00', '13.04', '14.29', '12.50', '14.29', '14.53', '11.11']

# Convert to floats
errorRateListOfFast = [float(x) for x in errorRateListOfFast]
errorRateListOfSlow = [float(x) for x in errorRateListOfSlow]

opacity = 0.4
bar_width = 0.35

plt.xlabel('Tasks')
plt.ylabel('Error Rate')

plt.xticks(range(len(errorRateListOfFast)),('[10-20)', '[20-30)', '[30-50)', '[50-70)','[70-90)', '[90-120)', ' [120 < )'), rotation=30)
bar1 = plt.bar(np.arange(len(errorRateListOfFast)) + bar_width, errorRateListOfFast, bar_width, align='center', alpha=opacity, color='b', label='Fast <= 6 sec.')
bar2 = plt.bar(range(len(errorRateListOfSlow)), errorRateListOfSlow, bar_width, align='center', alpha=opacity, color='r', label='Slower > 6 sec.')

# Add counts above the two bar graphs
for rect in bar1 + bar2:
    height = rect.get_height()
    plt.text(rect.get_x() + rect.get_width() / 2.0, height, f'{height:.0f}', ha='center', va='bottom')

plt.legend()
plt.tight_layout()
plt.show()
```
Giving you: ha='center' and va='bottom' refer to how the text is aligned in relation to the x and y co-ordinates, i.e. horizontal and vertical alignment.


Question:
Matplotlib how to change figsize for matshow How to change figsize for matshow() in jupyter notebook? For example this code change figure size
```
%matplotlib inline
import matplotlib.pyplot as plt
import pandas as pd

d = pd.DataFrame({'one' : [1, 2, 3, 4, 5],
                  'two' : [4, 3, 2, 1, 5]})
plt.figure(figsize=(10,5))
plt.plot(d.one, d.two)
```
But code below doesn't work
```
%matplotlib inline
import matplotlib.pyplot as plt
import pandas as pd

d = pd.DataFrame({'one' : [1, 2, 3, 4, 5],
                  'two' : [4, 3, 2, 1, 5]})
plt.figure(figsize=(10,5))
plt.matshow(d.corr())
```

Response:
By default, plt.matshow() produces its own figure, so in combination with plt.figure() two figures will be created and the one that hosts the matshow plot is not the one that has the figsize set. There are two options: Use the fignum argument
```
plt.figure(figsize=(10,5))
plt.matshow(d.corr(), fignum=1)
```
Plot the matshow using matplotlib.axes.Axes.matshow instead of pyplot.matshow.
```
fig, ax = plt.subplots(figsize=(10,5))
ax.matshow(d.corr())
```


Question:
Fit a gaussian function I have a histogram (see below) and I am trying to find the mean and standard deviation along with code which fits a curve to my histogram. I think there is something in SciPy or matplotlib that can help, but every example I've tried doesn't work.
```
import matplotlib.pyplot as plt
import numpy as np

with open('gau_b_g_s.csv') as f:
    v = np.loadtxt(f, delimiter= ',', dtype="float", skiprows=1, usecols=None)

fig, ax = plt.subplots()

plt.hist(v, bins=500, color='#7F38EC', histtype='step')

plt.title("Gaussian")
plt.axis([-1, 2, 0, 20000])

plt.show()
```

Response:
Take a look at this answer for fitting arbitrary curves to data. Basically you can use scipy.optimize.curve_fit to fit any function you want to your data. The code below shows how you can fit a Gaussian to some random data (credit to this SciPy-User mailing list post).
```
import numpy
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt

# Define some test data which is close to Gaussian
data = numpy.random.normal(size=10000)

hist, bin_edges = numpy.histogram(data, density=True)
bin_centres = (bin_edges[:-1] + bin_edges[1:])/2

# Define model function to be used to fit to the data above:
def gauss(x, *p):
    A, mu, sigma = p
    return A*numpy.exp(-(x-mu)**2/(2.*sigma**2))

# p0 is the initial guess for the fitting coefficients (A, mu and sigma above)
p0 = [1., 0., 1.]

coeff, var_matrix = curve_fit(gauss, bin_centres, hist, p0=p0)

# Get the fitted curve
hist_fit = gauss(bin_centres, *coeff)

plt.plot(bin_centres, hist, label='Test data')
plt.plot(bin_centres, hist_fit, label='Fitted data')

# Finally, lets get the fitting parameters, i.e. the mean and standard deviation:
print 'Fitted mean = ', coeff[1]
print 'Fitted standard deviation = ', coeff[2]

plt.show()
```


Question:
How to plot a bar graph from a pandas series? Consider my series as below: First column is article_id and the second column is frequency count.
```
article_id
1         39
2         49
3        187
4        159
5        158
        ...
16947     14
16948      7
16976      2
16977      1
16978      1
16980      1

Name: article_id, dtype: int64
```
I got this series from a dataframe with the following command:
```
logs.loc[logs['article_id'] <= 17029].groupby('article_id')['article_id'].count()
```
logs is the dataframe here and article_id is one of the columns in it. How do I plot a bar chart(using Matlplotlib) such that the article_id is on the X-axis and the frequency count on the Y-axis ? My natural instinct was to convert it into a list using .tolist() but that doesn't preserve the article_id.

Response:
IIUC you need Series.plot.bar:
```
#pandas 0.17.0 and above
s.plot.bar()
#pandas below 0.17.0
s.plot('bar')
```
Sample:
```
import pandas as pd
import matplotlib.pyplot as plt

s = pd.Series({16976: 2, 1: 39, 2: 49, 3: 187, 4: 159,
               5: 158, 16947: 14, 16977: 1, 16948: 7, 16978: 1, 16980: 1},
               name='article_id')
print (s)
1         39
2         49
3        187
4        159
5        158
16947     14
16948      7
16976      2
16977      1
16978      1
16980      1
Name: article_id, dtype: int64

s.plot.bar()

plt.show()
```


Question:
Show mean in the box plot I am new to Matplotlib, and as I am learning how to draw box plot in python, I was wondering if there is a way to show mean in the box plots? Below is my code..
```
from pylab import *
import matplotlib.pyplot as plt
data1=np.random.rand(100,1)
data2=np.random.rand(100,1)
data_to_plot=[data1,data2]
#Create a figure instance
fig = plt.figure(1, figsize=(9, 6))
# Create an axes instance
axes = fig.add_subplot(111)
# Create the boxplot
bp = axes.boxplot(data_to_plot,**showmeans=True**)
```
Even though I have showmean flag on, it gives me the following error.
```
TypeError: boxplot() got an unexpected keyword argument 'showmeans'
```

Response:
This is a minimal example and produces the desired result:
```
import matplotlib.pyplot as plt
import numpy as np

data_to_plot = np.random.rand(100,5)

fig = plt.figure(1, figsize=(9, 6))
ax = fig.add_subplot(111)
bp = ax.boxplot(data_to_plot, showmeans=True)

plt.show()
```
EDIT: If you want to achieve the same with matplotlib version 1.3.1 you'll have to plot the means manually. This is an example of how to do it:
```
import matplotlib.pyplot as plt
import numpy as np

data_to_plot = np.random.rand(100,5)
positions = np.arange(5) + 1

fig, ax = plt.subplots(1,2, figsize=(9,4))

# matplotlib > 1.4
bp = ax[0].boxplot(data_to_plot, positions=positions, showmeans=True)
ax[0].set_title("Using showmeans")

#matpltolib < 1.4
bp = ax[1].boxplot(data_to_plot, positions=positions)
means = [np.mean(data) for data in data_to_plot.T]
ax[1].plot(positions, means, 'rs')
ax[1].set_title("Plotting means manually")

plt.show()
```
Result:


Question:
Removing Horizontal Lines in image (OpenCV, Python, Matplotlib) Using the following code I can remove horizontal lines in images. See result below.
```
import cv2
from matplotlib import pyplot as plt

img = cv2.imread('image.png',0)

laplacian = cv2.Laplacian(img,cv2.CV_64F)
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=5)

plt.subplot(2,2,1),plt.imshow(img,cmap = 'gray')
plt.title('Original'), plt.xticks([]), plt.yticks([])
plt.subplot(2,2,2),plt.imshow(laplacian,cmap = 'gray')
plt.title('Laplacian'), plt.xticks([]), plt.yticks([])
plt.subplot(2,2,3),plt.imshow(sobelx,cmap = 'gray')
plt.title('Sobel X'), plt.xticks([]), plt.yticks([])

plt.show()
```
The result is pretty good, not perfect but good. What I want to achieve is the one showed here. I am using this code. Source image.. One of my questions is: how to save the Sobel X without that grey effect applied ? As original but processed.. Also, is there a better way to do it ? EDIT Using the following code for the source image is good. Works pretty well.
```
import cv2
import numpy as np

img = cv2.imread("image.png")
img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

img = cv2.bitwise_not(img)
th2 = cv2.adaptiveThreshold(img,255, cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,15,-2)
cv2.imshow("th2", th2)
cv2.imwrite("th2.jpg", th2)
cv2.waitKey(0)
cv2.destroyAllWindows()

horizontal = th2
vertical = th2
rows,cols = horizontal.shape

#inverse the image, so that lines are black for masking
horizontal_inv = cv2.bitwise_not(horizontal)
#perform bitwise_and to mask the lines with provided mask
masked_img = cv2.bitwise_and(img, img, mask=horizontal_inv)
#reverse the image back to normal
masked_img_inv = cv2.bitwise_not(masked_img)
cv2.imshow("masked img", masked_img_inv)
cv2.imwrite("result2.jpg", masked_img_inv)
cv2.waitKey(0)
cv2.destroyAllWindows()

horizontalsize = int(cols / 30)
horizontalStructure = cv2.getStructuringElement(cv2.MORPH_RECT, (horizontalsize,1))
horizontal = cv2.erode(horizontal, horizontalStructure, (-1, -1))
horizontal = cv2.dilate(horizontal, horizontalStructure, (-1, -1))
cv2.imshow("horizontal", horizontal)
cv2.imwrite("horizontal.jpg", horizontal)
cv2.waitKey(0)
cv2.destroyAllWindows()

verticalsize = int(rows / 30)
verticalStructure = cv2.getStructuringElement(cv2.MORPH_RECT, (1, verticalsize))
vertical = cv2.erode(vertical, verticalStructure, (-1, -1))
vertical = cv2.dilate(vertical, verticalStructure, (-1, -1))
cv2.imshow("vertical", vertical)
cv2.imwrite("vertical.jpg", vertical)
cv2.waitKey(0)
cv2.destroyAllWindows()

vertical = cv2.bitwise_not(vertical)
cv2.imshow("vertical_bitwise_not", vertical)
cv2.imwrite("vertical_bitwise_not.jpg", vertical)
cv2.waitKey(0)
cv2.destroyAllWindows()

#step1
edges = cv2.adaptiveThreshold(vertical,255, cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,3,-2)
cv2.imshow("edges", edges)
cv2.imwrite("edges.jpg", edges)
cv2.waitKey(0)
cv2.destroyAllWindows()

#step2
kernel = np.ones((2, 2), dtype = "uint8")
dilated = cv2.dilate(edges, kernel)
cv2.imshow("dilated", dilated)
cv2.imwrite("dilated.jpg", dilated)
cv2.waitKey(0)
cv2.destroyAllWindows()

# step3
smooth = vertical.copy()

#step 4
smooth = cv2.blur(smooth, (4,4))
cv2.imshow("smooth", smooth)
cv2.imwrite("smooth.jpg", smooth)
cv2.waitKey(0)
cv2.destroyAllWindows()

#step 5
(rows, cols) = np.where(img == 0)
vertical[rows, cols] = smooth[rows, cols]

cv2.imshow("vertical_final", vertical)
cv2.imwrite("vertical_final.jpg", vertical)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
But if I have this image ? I tried to execute the code above and the result is really poor... Other images which I am working on are these...

Response:
Obtain binary image. Load the image, convert to grayscale, then Otsu's threshold to obtain a binary black/white image. Detect and remove horizontal lines. To detect horizontal lines, we create a special horizontal kernel and morph open to detect horizontal contours. From here we find contours on the mask and "fill in" the detected horizontal contours with white to effectively remove the lines Repair image. At this point the image may have gaps if the horizontal lines intersected through characters. To repair the text, we create a vertical kernel and morph close to reverse the damage After converting to grayscale, we Otsu's threshold to obtain a binary image
```
image = cv2.imread('1.png')
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
```
Next we create a special horizontal kernel to detect horizontal lines. We draw these lines onto a mask and then find contours on the mask. To remove the lines, we fill in the contours with white Detected lines Mask Filled in contours
```
# Remove horizontal
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (25,1))
detected_lines = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel, iterations=2)
cnts = cv2.findContours(detected_lines, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    cv2.drawContours(image, [c], -1, (255,255,255), 2)
```
The image currently has gaps. To fix this, we construct a vertical kernel to repair the image
```
# Repair image
repair_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1,6))
result = 255 - cv2.morphologyEx(255 - image, cv2.MORPH_CLOSE, repair_kernel, iterations=1)
```
Note depending on the image, the size of the kernel will change. You can think of the kernel as (horizontal, vertical). For instance, to detect longer lines, we could use a (50,1) kernel instead. If we wanted thicker lines, we could increase the 2nd parameter to say (50,2). Here's the results with the other images Detected lines Original -> Removed Detected lines Original -> Removed Full code
```
import cv2

image = cv2.imread('1.png')
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

# Remove horizontal
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (25,1))
detected_lines = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel, iterations=2)
cnts = cv2.findContours(detected_lines, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    cv2.drawContours(image, [c], -1, (255,255,255), 2)

# Repair image
repair_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1,6))
result = 255 - cv2.morphologyEx(255 - image, cv2.MORPH_CLOSE, repair_kernel, iterations=1)

cv2.imshow('thresh', thresh)
cv2.imshow('detected_lines', detected_lines)
cv2.imshow('image', image)
cv2.imshow('result', result)
cv2.waitKey()
```


Question: Annotate Subplots in a Figure with A, B, C When submitting papers to scientific journals one quite frequently needs to enumerate the different subplots of a figure with A, B, ... . This sounds like a very common problem and I was trying to find an elegant way to do that automatically with matplotlib, but I was surprised to find nothing on it. But maybe I am not using the right search terms. Ideally, I am searching for a way to annotate such that the letters stay in place relative to the subplot if the figure is resized or the subplot is moved via fig.subplots_adjust, fig.tight_layout, or similar. Any help or solution will appreciated.

Response:
If you want the annotation relative to the subplot then plotting it using ax.text seems the most convenient way to me. Consider something like:
```
import numpy as np
import matplotlib.pyplot as plt
import string

fig, axs = plt.subplots(2,2,figsize=(8,8))
axs = axs.flat

for n, ax in enumerate(axs):

    ax.imshow(np.random.randn(10,10), interpolation='none')
    ax.text(-0.1, 1.1, string.ascii_uppercase[n], transform=ax.transAxes,
            size=20, weight='bold')
```
edit: With the new plt.subplot_mosiac, the example above can be written as. Perhaps slightly more elagant. And consider adding constrained_layout=True.
```py
fig, axs = plt.subplot_mosaic("AB;CD", figsize=(10,10))

for n, (key, ax) in enumerate(axs.items()):

    ax.imshow(np.random.randn(10,10), interpolation='none')
    ax.text(-0.1, 1.1, key, transform=ax.transAxes,
            size=20, weight='bold')
```


Question: Embedding a matplotlib figure inside a WxPython panel How do I embed a matplotlib figure object inside a WxPython panel? I googled around and saw complicated examples involving interactive graphics and other extra stuff. Can anybody help with a minimal example?

Response:
This is a minimal example for a Panel with a matplotlib canvas:
```
from numpy import arange, sin, pi
import matplotlib
matplotlib.use('WXAgg')

from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.backends.backend_wx import NavigationToolbar2Wx
from matplotlib.figure import Figure

import wx

class CanvasPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.figure = Figure()
        self.axes = self.figure.add_subplot(111)
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        self.SetSizer(self.sizer)
        self.Fit()

    def draw(self):
        t = arange(0.0, 3.0, 0.01)
        s = sin(2 * pi * t)
        self.axes.plot(t, s)

if __name__ == "__main__":
    app = wx.PySimpleApp()
    fr = wx.Frame(None, title='test')
    panel = CanvasPanel(fr)
    panel.draw()
    fr.Show()
    app.MainLoop()
```


Question:
How to display LaTeX f-strings in matplotlib [duplicate] This question already has an answer here: Format a string that has extra curly braces in it (1 answer) Closed 5 years ago. The community reviewed whether to reopen this question 3 years ago and left it closed: Original close reason(s) were not resolved In Python 3.6, there is the new f-string to include variables in strings which is great, but how do you correctly apply these strings to get super or subscripts printed for matplotlib? (to actually see the result with the subscript, you need to draw the variable foo on a matplotlib plot) In other words how do I get this behaviour:
```
var = 123
    foo = r'text$_{%s}$' % var
    text<sub>123</sub>
```
Using the new f-string syntax? So far, I have tried using a raw-string literal combined with an f-string, but this only seems to apply the subscript to the first character of the variable:
```
var = 123
    foo = fr'text$_{var}$'
    text<sub>1</sub>23
```
Because the { has an ambiguous function as delimiting what r should consider subscript and what f delimits as a place for the variable.

Response:
You need to escape the curly brackets by doubling them up, and then add in one more to use in the LaTeX formula. This gives:
```
foo = f'text$_{{{var}}}$'
```
Example:
```
plt.figure()
plt.plot([1,2,3], [3,4,5])
var = 123
plt.text(1, 4,f'text$_{{{var}}}$')
```
Output: Incidentally, in this example, you don't actually need to use a raw-string literal.


Question: Matplotlib boxplot x axis It's easier to ask this with a figure. At the moment i obtain the following boxplot graph using matplotlib: Is there a way to obtain a figure like that, but with each box in a position coherent with the corresponding x-axis number (like in a normal scatter plot, but with boxes instead of points)? At the moment the numbers on the x-axis are added by means of the labels= argument.

Response:
You need to specify the positions argument to the boxplot constructor.
```
from matplotlib import pyplot as plt

plt.boxplot([[1,4],[2,5],[3,6]], positions=[2,4,5.5])
```
By default it uses the values [1, 2, ..., n] but you can specify a different x position for each bar and the xticks will be updated automatically.


Question:
Matplotlib: Add colorbar to non-mappable object I have a series of lines representing the change of a variable; each with a unique color. For that reason I want to add a colorbar next to the plot. The desired output is shown below. The problem is that plot is a non-mappable object, i.e. the colorbar has to be added manually. I consider my current solution (below) sub-optimal as it involves size parameters of which I have no interest in controlling. I'd prefer a similar solution as for a mappable object (example below current solution). Desired output Current solution
```
import numpy             as np
import matplotlib        as mpl
import matplotlib.pyplot as plt

x    = np.linspace(0, 5, 100)
N    = 20
cmap = plt.get_cmap('jet',N)

fig  = plt.figure(figsize=(8,6))
ax1  = fig.add_axes([0.10,0.10,0.70,0.85])

for i,n in enumerate(np.linspace(0,2,N)):
    y = np.sin(x)*x**n
    ax1.plot(x,y,c=cmap(i))

plt.xlabel('x')
plt.ylabel('y')

ax2  = fig.add_axes([0.85,0.10,0.05,0.85])
norm = mpl.colors.Normalize(vmin=0,vmax=2)
cb1  = mpl.colorbar.ColorbarBase(ax2,cmap=cmap,norm=norm,orientation='vertical')

plt.show()
```
Desired solution (obviously replacing imshow)
```
fig,ax = plt.subplots()
cax    = ax.imshow(..)
cbar   = fig.colorbar(cax,aspect=10)
plt.show()
```

Response:
You may define your own ScalarMappable and use it just as if it was present in the plot. (Note that I changed the numbero f colors to 21 to have nice spacings of 0.1)
```
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

x = np.linspace(0, 5, 100)
N = 21
cmap = plt.get_cmap('jet',N)

fig = plt.figure(figsize=(8,6))
ax1 = fig.add_axes([0.10,0.10,0.70,0.85])

for i,n in enumerate(np.linspace(0,2,N)):
    y = np.sin(x)*x**n
    ax1.plot(x,y,c=cmap(i))

plt.xlabel('x')
plt.ylabel('y')

norm = mpl.colors.Normalize(vmin=0,vmax=2)
sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm)
sm.set_array([])
plt.colorbar(sm, ticks=np.linspace(0,2,N),
             boundaries=np.arange(-0.05,2.1,.1))

plt.show()
```


Question:
How to set Dataframe Column value as X-axis labels Say I have data in following format:
```
Region   Men   Women
City1    10   5
City2    50   89
```
When I load it in Dataframe and plot graph, it shows index as X-axis labels instead of Region name. How do I get names on X-axis? So far I tried:
```
import pandas as pd
import matplotlib.pyplot as plt
plt.style.use('ggplot')
ax = df[['Men','Women']].plot(kind='bar', title ="Population",figsize=(15,10),legend=True, fontsize=12)
ax.set_xlabel("Areas",fontsize=12)
ax.set_ylabel("Population",fontsize=12)
plt.show()
```
Currently it shows x ticks as 0,1,2..

Response:
plot.bar() method inherits its arguments from plot(), which has rot argument: from the docs: rot : int, default None Rotation for ticks (xticks for vertical, yticks for horizontal plots) it also uses per default index as ticks for x axis: use_index : boolean, default True Use index as ticks for x axis
```

```python
df.plot.bar(x='Region', rot=0, title='Population', figsize=(15,10), fontsize=12)
#Output
#<matplotlib.axes._subplots.AxesSubplot at 0xd09ff28>
#```
#alternatively you can set index explicitly - it might be useful for multi-level indexes (axes):
#```
#df.set_index('Region').plot.bar(rot=0, title='Population', figsize=(15,10), fontsize=12)
#```
```


Question: How to set number of ticks in plt.colorbar? When I plot a matrix with a colorbar, then the colorbar has 10 ticks. Since the colorbar has to be pretty small, the ticklabels overlap. Therefore I want to reduce the number of ticks from 10 to 5. I do not want to reduce the font size! Is there an easy way to do this? I do not want to set the ticks manually...

Response:
The MaxNLocator ticker might suit your purposes? class matplotlib.ticker.MaxNLocator Select no more than N intervals at nice locations For example:
```
from matplotlib import ticker

# (generate plot here)
cb = plt.colorbar()
tick_locator = ticker.MaxNLocator(nbins=5)
cb.locator = tick_locator
cb.update_ticks()
plt.show()
```


Question: Plotting a line over several graphs I don't know how this thing is called, or even how to describe it, so the title may be a little bit misleading. The first attached graph was created with pyplot. I would like to draw a straight line that goes through all graphs instead of the three red dot I currently use. Is it possible in pyplot? Second image is what I am looking for.

Response:
You can pull this off by turning clipping off for the relevant lines. There's probably a cleaner way to do this -- you might be able to draw lines on the main frame directly -- but the following worked for me:
```
from matplotlib import pyplot as plt
from numpy import arange, sin, cos

xx = arange(100)
cut = (xx > 0) & (xx % 17 == 0)
y1 = sin(xx)
y2 = (xx**2) % 2.0+cos(xx+0.5)

fig = plt.figure()
ax1 = fig.add_subplot(211)
ax1.plot(xx, y1, c="blue",zorder=1)
ax1.scatter(xx[cut], y1[cut], c="red",zorder=2)
ax2 = fig.add_subplot(212)
ax2.plot(xx, y2, c="green",zorder=1)
ax2.scatter(xx[cut], y2[cut], c="red",zorder=2)

for x in xx[cut]:
    ax1.axvline(x=x,ymin=-1.2,ymax=1,c="red",linewidth=2,zorder=0, clip_on=False)
    ax2.axvline(x=x,ymin=0,ymax=1.2,c="red",linewidth=2, zorder=0,clip_on=False)

plt.draw()
fig.savefig('pic.png')
```
With a bit more work you could modify the line drawing to handle the general case of multiple subplot windows, but I'm profoundly lazy. :^)


Question: Python : Matplotlib annotate line break (with and without latex) I have a very basic question : how to do a line break with matplotlib in python with an "annotate" command. I tried "\" and "\n" but it does not work. And how to do this for a "Latex" annotation and for a normal text annotation ? Thank you very much.

Response:
What exactly did you try? Were you, by chance, using a raw string (e.g. r"whatever")? '\n' works perfectly, but if you're using a raw string to avoid latex sequences being interpreted as an escape, it will be interpreted by python as '\' and 'n' instead of a newline. As an example:
```
import matplotlib.pyplot as plt

plt.annotate('Testing\nThis\nOut', xy=(0.5, 0.5))

plt.show()
```
On the other hand, if we use a raw string:
```
import matplotlib.pyplot as plt

plt.annotate(r'Testing\nThis\nOut', xy=(0.5, 0.5))

plt.show()
```


Question:
How can I place a table on a plot in Matplotlib? I'm not having any success in getting the matplotlib table commands to work. Here's an example of what I'd like to do: Can anyone help with the table construction code?
```
import pylab as plt

plt.figure()
ax=plt.gca()
y=[1,2,3,4,5,4,3,2,1,1,1,1,1,1,1,1]
plt.plot([10,10,14,14,10],[2,4,4,2,2],'r')
col_labels=['col1','col2','col3']
row_labels=['row1','row2','row3']
table_vals=[11,12,13,21,22,23,31,32,33]
# the rectangle is where I want to place the table
plt.text(11,4.1,'Table Title',size=8)
plt.plot(y)
plt.show()
```

Response:
AFAIK, you can't arbitrarily place a table on the matplotlib plot using only native matplotlib features. What you can do is take advantage of the possibility of latex text rendering. However, in order to do this you should have working latex environment in your system. If you have one, you should be able to produce graphs such as below:
```
import pylab as plt
import matplotlib as mpl

mpl.rc('text', usetex=True)
plt.figure()
ax=plt.gca()
y=[1,2,3,4,5,4,3,2,1,1,1,1,1,1,1,1]
#plt.plot([10,10,14,14,10],[2,4,4,2,2],'r')
col_labels=['col1','col2','col3']
row_labels=['row1','row2','row3']
table_vals=[11,12,13,21,22,23,31,32,33]
table = r'''\begin{tabular}{ c | c | c | c } & col1 & col2 & col3 \\\hline row1 & 11 & 12 & 13 \\\hline row2 & 21 & 22 & 23 \\\hline  row3 & 31 & 32 & 33 \end{tabular}'''
plt.text(9,3.4,table,size=12)
plt.plot(y)
plt.show()
```
The result is: Please take in mind that this is quick'n'dirty example; you should be able to place the table correctly by playing with text coordinates. Please also refer to the docs if you need to change fonts etc. UPDATE: more on pyplot.table According to the documentation, plt.table adds a table to current axes. From sources it's obvious, that table location on the graph is determined in relation to axes. Y coordinate can be controlled with keywords top (above graph), upper (in the upper half), center (in the center), lower (in the lower half) and bottom (below graph). X coordinate is controlled with keywords left and right. Any combination of the two works, e.g. any of top left, center right and bottom is OK to use. So the closest graph to what you want could be made with:
```
import matplotlib.pylab as plt

plt.figure()
ax=plt.gca()
y=[1,2,3,4,5,4,3,2,1,1,1,1,1,1,1,1]
#plt.plot([10,10,14,14,10],[2,4,4,2,2],'r')
col_labels=['col1','col2','col3']
row_labels=['row1','row2','row3']
table_vals=[[11,12,13],[21,22,23],[31,32,33]]
# the rectangle is where I want to place the table
the_table = plt.table(cellText=table_vals,
                  colWidths = [0.1]*3,
                  rowLabels=row_labels,
                  colLabels=col_labels,
                  loc='center right')
plt.text(12,3.4,'Table Title',size=8)

plt.plot(y)
plt.show()
```
And this gives you Hope this helps!


Question: How to plot precision and recall of multiclass classifier? I'm using scikit learn, and I want to plot the precision and recall curves. the classifier I'm using is RandomForestClassifier. All the resources in the documentations of scikit learn uses binary classification. Also, can I plot a ROC curve for multiclass? Also, I only found for SVM for multilabel and it has a decision_function which RandomForest doesn't have

Response:
From scikit-learn documentation: Precision-Recall: Precision-recall curves are typically used in binary classification to study the output of a classifier. In order to extend the precision-recall curve and average precision to multi-class or multi-label classification, it is necessary to binarize the output. One curve can be drawn per label, but one can also draw a precision-recall curve by considering each element of the label indicator matrix as a binary prediction (micro-averaging). Receiver Operating Characteristic (ROC): ROC curves are typically used in binary classification to study the output of a classifier. In order to extend ROC curve and ROC area to multi-class or multi-label classification, it is necessary to binarize the output. One ROC curve can be drawn per label, but one can also draw a ROC curve by considering each element of the label indicator matrix as a binary prediction (micro-averaging). Therefore, you should binarize the output and consider precision-recall and roc curves for each class. Moreover, you are going to use predict_proba to get class probabilities. I divide the code into three parts: general settings, learning and prediction precision-recall curve ROC curve 1. general settings, learning and prediction
```
from sklearn.datasets import fetch_openml
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.multiclass import OneVsRestClassifier
from sklearn.metrics import precision_recall_curve, roc_curve
from sklearn.preprocessing import label_binarize

import matplotlib.pyplot as plt
#%matplotlib inline

mnist = fetch_openml("mnist_784")
y = mnist.target
y = y.astype(np.uint8)
n_classes = len(set(y))

Y = label_binarize(mnist.target, classes=[*range(n_classes)])

X_train, X_test, y_train, y_test = train_test_split(mnist.data,
                                                    Y,
                                                    random_state = 42)

clf = OneVsRestClassifier(RandomForestClassifier(n_estimators=50,
                             max_depth=3,
                             random_state=0))
clf.fit(X_train, y_train)

y_score = clf.predict_proba(X_test)
```
2. precision-recall curve
```
# precision recall curve
precision = dict()
recall = dict()
for i in range(n_classes):
    precision[i], recall[i], _ = precision_recall_curve(y_test[:, i],
                                                        y_score[:, i])
    plt.plot(recall[i], precision[i], lw=2, label='class {}'.format(i))

plt.xlabel("recall")
plt.ylabel("precision")
plt.legend(loc="best")
plt.title("precision vs. recall curve")
plt.show()
```
3. ROC curve
```
# roc curve
fpr = dict()
tpr = dict()

for i in range(n_classes):
    fpr[i], tpr[i], _ = roc_curve(y_test[:, i],
                                  y_score[:, i]))
    plt.plot(fpr[i], tpr[i], lw=2, label='class {}'.format(i))

plt.xlabel("false positive rate")
plt.ylabel("true positive rate")
plt.legend(loc="best")
plt.title("ROC curve")
plt.show()
```


Question:
Show the values in the grid using matplotlib I m trying to generate heatmaps for the some data and my code is shown below:
```
data = [['basis', 2007, 2008],
        [1, 2.2, 3.4],
        [2, 0, -2.2],
        [3, -4.1, -2.5],
        [4, -5.8, 1.2],
        [5, -5.4, -3.6],
        [6, 1.4, -5.9]]

x_header = data[0][1:]
y_header = [i for i in range(1, 13)]
data=data[1:]
for i in range(len(data)):
    data[i] = data[i][1:]
arr = np.array(data)
fig, ax = plt.subplots()
#heatmap = plt.pcolor(arr, cmap = 'RdBu')
norm = MidpointNormalize(midpoint=0)
im = ax.imshow(data, norm=norm, cmap=plt.cm.seismic, interpolation='none')

ax.set_xticks(np.arange(arr.shape[1]), minor=False)
ax.set_yticks(np.arange(arr.shape[0]), minor=False)
ax.xaxis.tick_top()
ax.set_xticklabels(x_header, rotation=90)
ax.set_yticklabels(y_header)

fig.colorbar(im)
plt.show()
```
It generates the image I also want to show values inside the grid. Is there any way to do that?

Response:
Sure, just do something like:
```
import matplotlib.pyplot as plt
import numpy as np

data = np.random.random((4, 4))

fig, ax = plt.subplots()
# Using matshow here just because it sets the ticks up nicely. imshow is faster.
ax.matshow(data, cmap='seismic')

for (i, j), z in np.ndenumerate(data):
    ax.text(j, i, '{:0.1f}'.format(z), ha='center', va='center')

plt.show()
```
However, the labels are hard to see, so you might want a box around them:
```
import matplotlib.pyplot as plt
import numpy as np

data = np.random.random((4, 4))

fig, ax = plt.subplots()
# Using matshow here just because it sets the ticks up nicely. imshow is faster.
ax.matshow(data, cmap='seismic')

for (i, j), z in np.ndenumerate(data):
    ax.text(j, i, '{:0.1f}'.format(z), ha='center', va='center',
            bbox=dict(boxstyle='round', facecolor='white', edgecolor='0.3'))

plt.show()
```
Also, in many cases, ax.annotate is more useful that ax.text. It's much more flexible in how you can position text, but it's also more complex. Have a look at the examples here: http://matplotlib.org/users/annotations_guide.html


Question:
Matplotlib colorbar ticks on left/opposite side One could generate a vertical colorbar like so(simplified):
```
import matplotlib.pyplot as plt
import matplotlib as mpl

plt.figure()
c_ax=plt.subplot(111)
cb = mpl.colorbar.ColorbarBase(c_ax,orientation='vertical')
plt.savefig('my_colorbar.png')
```
Resulting in something like this(rotated for space reasons): Is it possible to get the ticks labels on the opposite side?

Response:
You can switch the position of the ticks using c_ax.yaxis.set_ticks_position() So for your example:
```
import matplotlib.pyplot as plt
import matplotlib as mpl

plt.viridis()

fig=plt.figure()
c_ax=plt.subplot(199)

cb = mpl.colorbar.ColorbarBase(c_ax,orientation='vertical')

c_ax.yaxis.set_ticks_position('left')

plt.savefig('my_colorbar.png')
```
Note you can also move the colorbar label in a similar way:
```
c_ax.yaxis.set_label_position('left')
```
And finally, in case you have a horizontal colorbar, and want to move the ticks and labels to the top, you can use the equivalent function on the xaxis:
```
c_ax.xaxis.set_label_position('top')
c_ax.xaxis.set_ticks_position('top')
```


Question:
How to hide lines with .plot [duplicate] This question already has answers here: Remove line through legend marker with .plot (4 answers) Closed 8 years ago. I do not want to connect points with lines. I know that for that I can use scatter. But, scatter does not work after plot. So, basically I have to lists of points. The points from the first list I do want to connect with lines while the points from the second list should not be connect with lines. How can one achieve it in matplotlib? This is what I have tried:
```
plt.figure()
plt.plot(xys[:,0], xys[:,1], marker='o', color='g')

# WHAT SHOULD I DO HERE?
#plt.plot(xys_bad[:,0], xys_bad[:,1], color='r', linewidth=0.0, markersize = 10.0)
plt.scatter(xys_bad[:,0], xys_bad[:,1], color='r')

plt.show()
```

Response:
As describe in matplotlib documentation you should use the 'None' linestyle:
```
plt.plot(xys_bad[:,0], xys_bad[:,1], color='r', linestyle='None', markersize = 10.0)
```


Question: Converting image from RGB to HSV color space I couldn't find such function (i.e. RGB_to_HSV()) in Scipy or Matplotlib's documentations, and Google doesn't show pointers, except ActiveState recipe which demonstrates rgb2hsv function, though not usable on Numpy array as is. Does someone know of a shortcut? Edit: Sorry, just found matplotlib.colors.rgb_to_hsv() which is exactly what I was looking for. Should I delete this question?

Response: Matplotlib provides RGB to HSV conversion function: matplotlib.colors.rgb_to_hsv(): matplotlib.colors.rgb_to_hsv(arr) convert rgb values in a numpy array to hsv values input and output arrays should have shape (M,N,3)


Question:
How to have actual values in matplotlib Pie Chart displayed I have a pie chart drawing the values extracted from a CSV file. The proportion of the values are currently displayed with the percentage displayed "autopct='%1.1f%%'". Is there a way to display the actual values which are represented in the dataset for each slice.
```
#Pie for Life Expectancy in Boroughs
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt

# show plots inline
%matplotlib inline

# use ggplot style
matplotlib.style.use('ggplot')

#read data
lifeEx = pd.read_csv('LEpie.csv')

#Select columns
df = pd.DataFrame()
df['LB'] = lifeEx[['Regions']]
df['LifeEx'] = lifeEx[['MinLF']]
colorz = ['#B5DF00','#AD1FFF', '#BF1B00','#5FB1FF','#FFC93F']
exploda = (0, 0, 0, 0.1, 0)

#plotting
plt.pie(df['LifeEx'], labels=df['LB'], colors=colorz, autopct='%1.1f%%', explode = exploda, shadow = True,startangle=90)

#labeling
plt.title('Min Life expectancy across London Regions', fontsize=12)
```

Response:
Using the autopct keyword As we know that the percentage shown times the sum of all actual values must be the actual value, we can define this as a function and supply this function to plt.pie using the autopct keyword.
```
import matplotlib.pyplot as plt
import numpy

labels = 'Frogs', 'Hogs', 'Dogs'
sizes = numpy.array([5860, 677, 3200])
colors = ['yellowgreen', 'gold', 'lightskyblue']

def absolute_value(val):
    a  = numpy.round(val/100.*sizes.sum(), 0)
    return a

plt.pie(sizes, labels=labels, colors=colors,
        autopct=absolute_value, shadow=True)

plt.axis('equal')
plt.show()
```
Care must be taken since the calculation involves some error, so the supplied value is only accurate to some decimal places. A little bit more advanced may be the following function, that tries to get the original value from the input array back by comparing the difference between the calculated value and the input array. This method does not have the problem of inaccuracy but relies on input values which are sufficiently distinct from one another.
```
def absolute_value2(val):
    a  = sizes[ numpy.abs(sizes - val/100.*sizes.sum()).argmin() ]
    return a
```
Changing text after pie creation The other option is to first let the pie being drawn with the percentage values and replace them afterwards. To this end, one would store the autopct labels returned by plt.pie() and loop over them to replace the text with the values from the original array. Attention, plt.pie() only returns three arguments, the last one being the labels of interest, when autopct keyword is provided so we set it to an empty string here.
```
labels = 'Frogs', 'Hogs', 'Dogs'
sizes = numpy.array([5860, 677, 3200])
colors = ['yellowgreen', 'gold', 'lightskyblue']

p, tx, autotexts = plt.pie(sizes, labels=labels, colors=colors,
        autopct="", shadow=True)

for i, a in enumerate(autotexts):
    a.set_text("{}".format(sizes[i]))

plt.axis('equal')
plt.show()
```


Question:
tick frequency when using seaborn/matplotlib boxplot I am plotting with seaborn a series of boxplots with
```py
sns.boxplot(full_array)
```
where full_array contains 200 arrays. Therefore, I have 200 boxplots and ticks on the x-axis from 0 to 200. The xticks are too close to each other and I would like to show only some of them, for instance, a labeled xtick every 20, or so. I tried several solutions as those mentioned here but they did not work. Every time I sample the xticks, I get wrong labels for the ticks, as they get numbered from 0 to N, with unit spacing. For instance, with the line
```py
ax.xaxis.set_major_locator(ticker.MultipleLocator(20))
```
I get a labelled xtick every 20 but the labels are 1, 2, 3, 4 instead of 20, 40, 60, 80...

Response:
The seaborn boxplot uses a FixedLocator and a FixedFormatter, i.e.
```
print ax.xaxis.get_major_locator()
print ax.xaxis.get_major_formatter()
```
prints
```
<matplotlib.ticker.FixedLocator object at 0x000000001FE0D668>
<matplotlib.ticker.FixedFormatter object at 0x000000001FD67B00>
```
It's therefore not sufficient to set the locator to a MultipleLocator since the ticks' values would still be set by the fixed formatter. Instead you would want to set a ScalarFormatter, which sets the ticklabels to correspond to the numbers at their position.
```
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import seaborn.apionly as sns
import numpy as np

ax = sns.boxplot(data = np.random.rand(20,30))

ax.xaxis.set_major_locator(ticker.MultipleLocator(5))
ax.xaxis.set_major_formatter(ticker.ScalarFormatter())

plt.show()
```


Question: Add custom border to certain cells in a matplotlib / seaborn plot Right now I`m using Seaborn's clustermap to generate some clustered heatmaps - so far so good. For a certain use case, I need to draw colored borders around specific cells. Is there a way to do that? Or with pcolormesh in matplotlib, or any other way?

Response:
You can do this by overplotting a Rectangle patch on the cell that you would want to highlight. Using the example plot from the seaborn docs
```
import seaborn as sns
import matplotlib.pyplot as plt
sns.set()
flights = sns.load_dataset("flights")
flights = flights.pivot("month", "year", "passengers")
g = sns.clustermap(flights)
```
We can highlight a cell by doing
```
from matplotlib.patches import Rectangle
ax = g.ax_heatmap

ax.add_patch(Rectangle((3, 4), 1, 1, fill=False, edgecolor='blue', lw=3))
plt.show()
```
This will produce the plot with a highlighted cell like so: Note the the indexing of the cells is 0 based with the origin at the bottom left.


Question: Python matplotlib change default color for values exceeding colorbar range When filling a grid with color such as when using contourf in pyplot, I need to find a way to change the color that pyplot uses to fill data that exceed the specified range of the colorbar. I wish to have a static colorbar that does not automatically change its range to fit the max/min of the data, so having occasional extreme values that exceed its bounds is inevitable, and colors need to be specified for such values. The default color for values exceeding the bounds of the colorbar is white, which can glaringly clash with the surrounding data if the colormap does not have white as its end colors. Example image is shown below - notice the white fill when values exceed the negative range of the colorbar: I believe there is a way to specify which color to use at each bound if they are exceeded by using rcParams, but I have not been able to find information on this anywhere. Any help would be appreciated.

Response:
The out-of-bounds colors can be set using the set_over and set_under methods of the colormap; see the documentation. You'll need to specify these values when you create your colormap. I don't see any matplotlibrc setting to set the default for this, though. You might also want to ask on the matplotlib mailing list. Edit: I see what is going on. The white area you describe is not beyond the limits of the color range. It is simply the blank background of the axes. Because you are only plotting certain levels, any levels outside that range will not be plotted at all, leaving those areas blank. To get what you want, do this:
```
cs = pyplot.contourf(x,y,z,levels=np.arange(50, 220, 20), cmap=pyplot.cm.jet, extend="both")
cs.cmap.set_under('k')
cs.set_clim(50, 210)
cb = pyplot.colorbar(cs)
```
The "extend" argument is the key; it tells contourf to go ahead and plot all contours, but collapse all outside the given range into "too big" and "too small" categories. The cs.set_clim call is necessary to work around an oddity I discovered in contourf while debugging this; for some reason when you use extend, it manipulates the data limits, so we need to reset them back to what we want them to be. Also, just as a matter of style, you shouldn't be doing things like Colormap.set_under(cmap,color='k'). This is calling the class method and explicitly passing the instance in, which is an odd way to do it. Just do cmap.set_under(color="k").


Question:
How to remove relative shift in matplotlib axis When I try to do a plot against a range with big enough numbers I get an axis with relative shift for all the ticks. For example:
```
plot([1000, 1001, 1002], [1, 2, 3])
```
I get these ticks on axis of abscissas:
```
0.0     0.5     1.0     1.5     2.0
                               +1e3
```
The question is how to remove +1e3 and get just:
```
1000.0  1000.5  1001.0  1001.5  1002.0
```

Response:
```
plot([1000, 1001, 1002], [1, 2, 3])
gca().get_xaxis().get_major_formatter().set_useOffset(False)
draw()
```
This grabs the current axes, gets the x-axis axis object and then the major formatter object and sets useOffset to false (doc). In newer versions (1.4+) of matplotlib the default behavior can be changed via the axes.formatter.useoffset rcparam.


Question:
Control the number of rows within a legend I am currently trying to plot a large amount of data on a single plot. I have structured my representation using repeated colors and symbols. However, when plotting the final results, the legend appears slightly off because I cannot control the number of rows within it. Thus, instead of getting 5 repeated green, then 5 repeated red, 5 repeated blue then 2 other, I get 5 -4 -4 -4 (where I would have prefered 5 - 5 - 5 - 2) You can clearly see this in attached image. Right now I use these options for the legend:
```
axp.legend(loc="lower right",ncol=4)
```

Response:
I also had this problem a couple of times and use this workaround by adding dummy items to the legend to fill the last column, if there are more elegant methods available I would also be very interested to hear about them.
```
import numpy as np
import matplotlib.pylab as pl

pl.figure()

pl.plot(np.arange(10), np.random.random([10,5]), color='r', label='red')
pl.plot(np.arange(10), np.random.random([10,5]), color='g', label='green')
pl.plot(np.arange(10), np.random.random([10,5]), color='b', label='blue')
pl.plot(np.arange(10), np.random.random([10,2]), color='k', label='black')

# Add empty dummy legend items
pl.plot(np.zeros(1), np.zeros([1,3]), color='w', alpha=0, label=' ')

pl.legend(ncol=4)
```


Question:
change strength of antialiasing in matplotlib Is it possible to increase the antialiasing in matplotlib? I can still see some aliasing in my data, I tried several backends and it is still there. The antialiasing flag of the lines is set. Here you can see what I mean It's a sample taken from a Screenshot. It's probably not the best example but I guess one can see the stairs in the line. It was taken with the wxagg backend. I'm using matplotlib version 1.01 with Windows 7. Update: I don't have the code which produced the previous picture anymore, but I still have the problem. Below is a simple code example which shows the aliasing.
```
import numpy as np
import matplotlib
matplotlib.use('wxAgg')
import matplotlib.pyplot as pl
print 'Backend:', pl.get_backend()

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

for a in range(10):
    pl.plot( x, a/10.*x, linewidth=1)

pl.show()
```
It print's Backend: WXAgg And the resulting plot looks like the following. Especially the lower red curve shows clear aliasing.

Response: If you save the picture as a .svg file, you will have infinite precision. You can then edit this .svg with something like InkScape, and get how much precision/antialiasing as you like.


Question:
Plot line graph from histogram data in matplotlib I have a numpy array of ints representing time periods, which I'm currently plotting in a histogram to get a nice distribution graph, using the following code:
```
ax.hist(data,bins=100,range=(minimum,maximum),facecolor="r")
```
However I'm trying to modify this graph to represent the exact same data using a line instead of bars, so I can overlay more samples to the same plot and have them be clear (otherwise the bars overlap each other). What I've tried so far is to collate the data array into an array of tuples containing (time, count), and then plot it using
```
ax.plot(data[:,0],data[:,1],color="red",lw=2)
```
However that's not giving me anything close, as I can't accurately simulate the bins option of the histogram in my plot. Is there a better way to do this?

Response:
I am very late to the party - but maybe this will be useful to someone else. I think what you need to do is set the histtype parameter to 'step', i.e.
```
ax.hist(data,bins=100,range=(minimum,maximum),facecolor="r", histtype = 'step')
```
See also http://matplotlib.sourceforge.net/examples/pylab_examples/histogram_demo_extended.html


Question:
How to automatically annotate maximum value in pyplot I'm trying to figure out how I can automatically annotate the maximum value in a figure window. I know you can do this by manually entering in x,y coordinates to annotate whatever point you want using the .annotate() method, but I want the annotation to be automatic, or to find the maximum point by itself. Here's my code so far:
```
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from pandas import Series, DataFrame

df = pd.read_csv('macrodata.csv') #Read csv file into dataframe
years = df['year'] #Get years column
infl = df['infl'] #Get inflation rate column

fig10 = plt.figure()
win = fig10.add_subplot(1,1,1)
fig10 = plt.plot(years, infl, lw = 2)

fig10 = plt.xlabel("Years")
fig10 = plt.ylabel("Inflation")
fig10 = plt.title("Inflation with Annotations")
```

Response:
If x and y are the arrays to plot, you get the coordinates of the maximum via
```
xmax = x[numpy.argmax(y)]
ymax = y.max()
```
This can be incorporated into a function that you may simply call with your data.
```
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-2,8, num=301)
y = np.sinc((x-2.21)*3)

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

def annot_max(x,y, ax=None):
    xmax = x[np.argmax(y)]
    ymax = y.max()
    text= "x={:.3f}, y={:.3f}".format(xmax, ymax)
    if not ax:
        ax=plt.gca()
    bbox_props = dict(boxstyle="square,pad=0.3", fc="w", ec="k", lw=0.72)
    arrowprops=dict(arrowstyle="->",connectionstyle="angle,angleA=0,angleB=60")
    kw = dict(xycoords='data',textcoords="axes fraction",
              arrowprops=arrowprops, bbox=bbox_props, ha="right", va="top")
    ax.annotate(text, xy=(xmax, ymax), xytext=(0.94,0.96), **kw)

annot_max(x,y)

ax.set_ylim(-0.3,1.5)
plt.show()
```


Question:
How to plot multiple pandas columns I have dataframe total_year, which contains three columns (year, action, comedy). How can I plot two columns (action and comedy) on y-axis? My code plots only one:
```
total_year[-15:].plot(x='year', y='action', figsize=(10,5), grid=True)
```

Response:
Several column names may be provided to the y argument of the pandas plotting function. Those should be specified in a list, as follows.
```
df.plot(x="year", y=["action", "comedy"])
```
Complete example:
```
import matplotlib.pyplot as plt
import pandas as pd

df = pd.DataFrame({"year": [1914,1915,1916,1919,1920],
                   "action" : [2.6,3.4,3.25,2.8,1.75],
                   "comedy" : [2.5,2.9,3.0,3.3,3.4] })
df.plot(x="year", y=["action", "comedy"])
plt.show()
```


Question:
matplotlib interactive mode: determine if figure window is still displayed I am using matplotlib in interactive mode to show the user a plot that will help them enter a range of variables. They have the option of hitting "?" to show this plot, and the prompt for variables will then be repeated. How do I know to not re-draw this plot if it's still being displayed? Superficially, I have this clunky (pseudo-ish) code:
```
answer = None
done_plot = False
while answer == None:
    answer = get_answer()
    if answer == '?':
        if done_plot:
            have_closed = True
            ##user's already requested a plot - has s/he closed it?
            ## some check here needed:
            have_closed = ?????

            if have_closed == False:
                print 'You already have the plot on display, will not re-draw'
                answer = None
                continue
        plt.ion()
        fig = plt.figure()
        ### plotting stuff
        done_plot = True
        answer = None
    else:
        ###have an answer from the user...
```
what can I use (in terms of plt.gca(), fig etc...) to determine if I need to re-plot? Is there a status somewhere I can check? Many thanks, David

Response:
In the same vein as unutbu's answer, you can also check whether a given figure is still opened with
```
import matplotlib.pyplot as plt

if plt.fignum_exists(<figure number>):
    # Figure is still opened
else:
    # Figure is closed
```
The figure number of a figure is in fig.number. PS: Note that the "number" in figure(num=…) can actually be a string: it is displayed in the window title. However, the figure still has a number attribute which is numeric. The original string num value can however be used with fignum_exists() (since 2015, according to Mark H, in the comments). PPS: That said, subplots(…, num=) properly recovers the existing figure with the given string number. Thus, figures are still known by their string number in some parts of Matplotlib.


Question: How can I convert numbers to a color scale in matplotlib? I'm making a bar plot and I want the colors of the bars to vary from red to blue according to a color gradient. I have a dimension of the data frame that tells me where on the red-blue scale each bar should be. My current method is to manually convert these values to RGB colors by linearly interpolating between the RGB red and blue colors but I want an automatic way of converting my numeric values to a color scale. I also need to be able to have a colorbar legend to help interpret it.

Response:
It's pretty straight forward to create a barchart and set the bar colors according to a value from the dataframe. A colormap and a normalization instance help converting the values to colors, which are understood by the color argument of matplotlib.Axes.bar. The colorbar is then created from a ScalarMappable using the same normalization and colormap as the bars.
```
import matplotlib.pyplot as plt
import matplotlib.colors
import numpy as np; np.random.seed(0)
import pandas as pd

x = np.arange(12)
y = np.random.rand(len(x))*51
c = np.random.rand(len(x))*3+1.5
df = pd.DataFrame({"x":x,"y":y,"c":c})

cmap = plt.cm.rainbow
norm = matplotlib.colors.Normalize(vmin=1.5, vmax=4.5)

fig, ax = plt.subplots()
ax.bar(df.x, df.y, color=cmap(norm(df.c.values)))
ax.set_xticks(df.x)

sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm)
sm.set_array([])  # only needed for matplotlib < 3.1
fig.colorbar(sm)

plt.show()
```
For using a custom colormap with bar plots see Barplot colored according a colormap?


Question: How to plot complex numbers (Argand Diagram) using matplotlib I'd like to create an Argand Diagram from a set of complex numbers using matplotlib. Are there any pre-built functions to help me do this? Can anyone recommend an approach? Image by LeonardoG, CC-SA-3.0

Response:
I'm not sure exactly what you're after here...you have a set of complex numbers, and want to map them to the plane by using their real part as the x coordinate and the imaginary part as y? If so you can get the real part of any python imaginary number with number.real and the imaginary part with number.imag. If you're using numpy, it also provides a set of helper functions numpy.real and numpy.imag etc. which work on numpy arrays. So for instance if you had an array of complex numbers stored something like this:
```

```python
a = n.arange(5) + 1j*n.arange(6,11)
```

```python
a
#Output
#array([ 0. +6.j,  1. +7.j,  2. +8.j,  3. +9.j,  4.+10.j])
#```
#...you can just do
#```
```

```python
fig,ax = subplots()
```

```python
ax.scatter(a.real,a.imag)
```
This plots dots on an argand diagram for each point. edit: For the plotting part, you must of course have imported matplotlib.pyplot via from matplotlib.pyplot import * or (as I did) use the ipython shell in pylab mode.
```


Question: How can I display text over columns in a bar chart in matplotlib? I have a bar chart and I want over each column to display some text,how can I do that ?

Response:
I believe this will point you in the right direction: http://matplotlib.sourceforge.net/examples/pylab_examples/barchart_demo.html. The part that you are most interested in is:
```
def autolabel(rects):
    for rect in rects:
        height = rect.get_height()
        plt.text(rect.get_x()+rect.get_width()/2., 1.05*height, '%d'%int(height),
                ha='center', va='bottom')
```
The placement of the text is determined by the height function, or the height of the column, and the number that is put on top of each column is written by: '%d' %int(height). So all you need to do is create an array of strings, called 'name', that you want at the top of the columns and iterate through. Be sure to change the format to be for a string (%s) and not a double.
```
def autolabel(rects):
# attach some text labels
    for ii,rect in enumerate(rects):
        height = rect.get_height()
        plt.text(rect.get_x()+rect.get_width()/2., 1.02*height, '%s'% (name[ii]),
                ha='center', va='bottom')
autolabel(rects1)
```
That should do it!


Question:
Can matplotlib errorbars have a linestyle set? Is it possible to set the same linestyle on matplotlib errorbars as the data points? In the example below, two lines are plotted. One of them is dashed because of the ls='-.' parameter. However, the errorbars are solid lines. Is it possible to modify the style/look of the errorbars to match the results line?
```
import matplotlib.pyplot as plt
import numpy as np

x = np.array(range(0,10))
y = np.array(range(0,10))
yerr = np.array(range(1,11)) / 5.0
yerr2 = np.array(range(1,11)) / 4.0

y2 = np.array(range(0,10)) * 1.2

plt.errorbar(x, y, yerr=yerr, lw=8, errorevery=2, ls='-.')
plt.errorbar(x, y2, yerr=yerr2, lw=8, errorevery=3)
plt.show()
```

Response:
It is trivial, changing the linestyle of the errorbars only require a simple .set_linestyle call:
```
eb1=plt.errorbar(x, y, yerr=yerr, lw=2, errorevery=2, ls='-.')
eb1[-1][0].set_linestyle('--') #eb1[-1][0] is the LineCollection objects of the errorbar lines
eb2=plt.errorbar(x, y2, yerr=yerr2, lw=2, errorevery=3)
eb2[-1][0].set_linestyle('-.')
```


Question:
canvas.mpl_connect in jupyter notebook I have the following code in test.py:
```
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(np.random.rand(10))

def onclick(event):
    print('button=%d, x=%d, y=%d, xdata=%f, ydata=%f' %
          (event.button, event.x, event.y, event.xdata, event.ydata))

cid = fig.canvas.mpl_connect('button_press_event', onclick)
```
when i run test.py in the command line by "python test.py", 'button=%d, x=%d, y=%d, xdata=%f, ydata=%f' gets printed as i click the plot however, the results are not printed in jupyter notebook. how to fix it? thanks in advance!

Response:
It will depend which backend you use in jupyter notebook. If you use the inline backend (i.e. %matplotlib inline), interactive features cannot work, because the plots are just png images. If you use the notebook backend (i.e. %matplotlib notebook) the interactive features do work, but the question would be where to print the result to. So in order to show the text one may add it to the figure as follows
```
%matplotlib notebook
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(np.random.rand(10))
text=ax.text(0,0, "", va="bottom", ha="left")

def onclick(event):
    tx = 'button=%d, x=%d, y=%d, xdata=%f, ydata=%f' % (event.button, event.x, event.y, event.xdata, event.ydata)
    text.set_text(tx)

cid = fig.canvas.mpl_connect('button_press_event', onclick)
```


Question:
matplotlib: limits when using plot and imshow in same axes I've been trying to plot an ellipse into an imshow plot. It works, but plotting the ellipse after plotting the image seems to increase xlim and ylim, resulting in a border, which I'd like to get rid of: Note that there is NO white border directly after calling imshow only. My code looks as follows:
```
self.dpi = 100
self.fig = Figure((6.0, 6.0), dpi=self.dpi)
self.canvas = FigureCanvas(self.fig)
self.canvas.setMinimumSize(800, 400)
self.cax = None
self.axes = self.fig.add_subplot(111)
self.axes.imshow(channel1, interpolation="nearest")
self.canvas.draw()
self.axes.plot(dat[0], dat[1], "b-")
```
I've tried setting the limits before and after calling "plot", with no effect
```
# get limits after calling imshow
xlim, ylim = pylab.xlim(), pylab.ylim()
...
# set limits before/after calling plot
self.axes.set_xlim(xlim)
self.axes.set_ylim(ylim)
```
How can I force plot not to increase existing figure limits? Solution (thanks to Joe):
```
#for newer matplotlib versions
self.axes.imshow(channel1, interpolation="nearest")
self.axes.autoscale(False)
self.axes.plot(dat[0], dat[1], "b-")

#for older matplotlib versions (worked for me using 0.99.1.1)
self.axes.imshow(channel1, interpolation="nearest")
self.axes.plot(dat[0], dat[1], "b-", scalex=False, scaley=False)
```

Response:
What's happening is that the axis is autoscaling to match the extents of each item you plot. Images are autoscaled much tighter than lines, etc (imshow basically calls ax.axis('image')). Getting the axis limits before and setting them after should have worked. (It's cleaner to just do limits = axes.axis() before and axes.axis(limits) after, though.) However, if you don't want things to autoscale, it's best to just turn autoscaling off after the initial plot. Try axes.autoscale(False) after plotting the image. As an example, compare this:
```
import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots()
ax.imshow(np.random.random((10,10)))
ax.plot(range(11))
plt.show()
```
With this:
```
import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots()
ax.imshow(np.random.random((10,10)))
ax.autoscale(False)
ax.plot(range(11))
plt.show()
```


Question:
Non-linear axes for imshow in matplotlib I am generating 2D arrays on log-spaced axes (for instance, the x pixel coordinates are generated using logspace(log10(0.95), log10(2.08), n). I want to display the image using a plain old imshow, in its native resolution and scaling (I don't need to stretch it; the data itself is already log scaled), but I want to add ticks, labels, lines that are in the correct place on the log axes. How do I do this? Ideally I could just use commands line axvline(1.5) and the line would be in the correct place (58% from the left), but if the only way is to manually translate between logscale coordinates and image coordinates, that's ok, too. For linear axes, using extents= in the call to imshow does what I want, but I don't see a way to do the same thing with a log axis. Example:
```
from matplotlib.colors import LogNorm

x = logspace(log10(10), log10(1000), 5)
imshow(vstack((x,x)), extent=[10, 1000, 0, 100], cmap='gray', norm=LogNorm(), interpolation='nearest')
axvline(100, color='red')
```
This example does not work, because extent= only applies to linear scales, so when you do axvline at 100, it does not appear in the center. I'd like the x axis to show 10, 100, 1000, and axvline(100) to put a line in the center at the 100 point, while the pixels remain equally spaced.

Response:
In my view, it is better to use pcolor and regular (non-converted) x and y values. pcolor gives you more flexibility and regular x and y axis are less confusing.
```
import pylab as plt
import numpy as np
from matplotlib.colors import LogNorm
from matplotlib.ticker import LogFormatterMathtext

x=np.logspace(1, 3, 6)
y=np.logspace(0, 2,3)
X,Y=np.meshgrid(x,y)
z = np.logspace(np.log10(10), np.log10(1000), 5)
Z=np.vstack((z,z))

im = plt.pcolor(X,Y,Z, cmap='gray', norm=LogNorm())
plt.axvline(100, color='red')

plt.xscale('log')
plt.yscale('log')

plt.colorbar(im, orientation='horizontal',format=LogFormatterMathtext())
plt.show()
```
As pcolor is slow, a faster solution is to use pcolormesh instead.
```
im = plt.pcolormesh(X,Y,Z, cmap='gray', norm=LogNorm())
```


Question: What is the name of the default seaborn color palette? From the top of https://seaborn.pydata.org/tutorial/color_palettes.html: But what is the default one called? That is, how do I invoke it in sns.set_palette() if I changed to a different palette and want to revert to the default? I also couldn't find an answer at https://seaborn.pydata.org/generated/seaborn.color_palette.html.

Response:
By default seaborn uses the matplotlib default colors. If you have not changed the default matplotlib parameters, this would be the colors from the "tab10" colormap.
```
sns.set_palette("tab10")
```
If however you have set some style beforehands, e.g. using sns.set(), this would set the palette to "deep". Hence you would get this back using
```
sns.set_palette("deep")
```


Question: Figure title with several colors Is it possible to have multiple font colors in matplotlib figure titles? Something like this

Response:
The following snippet seems to work.
```
import numpy as np
import matplotlib.pyplot as plt

x = np.arange(0, 5, 0.1);
y = np.sin(x)
fig1 = plt.figure(1)
fig1.text(0.45, 0.95, "Case A", ha="center", va="bottom", size="medium",color="red")
fig1.text(0.5, 0.95, "&", ha="center", va="bottom", size="medium")
fig1.text(0.55,0.95,"Case B", ha="center", va="bottom", size="medium",color="blue")
plt.plot(x, y)
plt.show()
```
As far as I can see the title generated by matplotlib title function only contains one text object and hence can only have one font color. This is the reason for making multiple text elements on the figure.


Question:
How do you change the default font color for all text in matplotlib? This only changed it for chart titles, but left axis titles the default color:
```
import matplotlib as mpl
mpl.rcParams['text.color'] = 'blue'
```

Response:
You can set each text property separately, e.g.:
```
COLOR = 'blue'
mpl.rcParams['text.color'] = COLOR
mpl.rcParams['axes.labelcolor'] = COLOR
mpl.rcParams['xtick.color'] = COLOR
mpl.rcParams['ytick.color'] = COLOR
```
The full list of params is at https://matplotlib.org/users/customizing.html.


Question:
How to label a line in matplotlib? I followed the documentation but still failed to label a line.
```
plt.plot([min(np.array(positions)[:,0]), max(np.array(positions)[:,0])], [0,0], color='k', label='East') # West-East
plt.plot([0,0], [min(np.array(positions)[:,1]), max(np.array(positions)[:,1])], color='k', label='North') # South-North
```
In the code snippet above, I am trying to plot out the North direction and the East direction. position contains the points to be plotted. But I end up with 2 straight lines with NO labels as follows: Where went wrong?

Response:
The argument label is used to set the string that will be shown in the legend. For example consider the following snippet:
```
import matplotlib.pyplot as plt
  plt.plot([1,2,3],'r-',label='Sample Label Red')
  plt.plot([0.5,2,3.5],'b-',label='Sample Label Blue')
  plt.legend()
  plt.show()
```
This will plot 2 lines as shown: The arrow function supports labels. Do check this link: http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.arrow


Question:
how to set readable xticks in seaborn's facetgrid? i have this plot of a dataframe with seaborn's facetgrid:
```
import seaborn as sns
import matplotlib.pylab as plt
import pandas
import numpy as np

plt.figure()
df = pandas.DataFrame({"a": map(str, np.arange(1001, 1001 + 30)),
                       "l": ["A"] * 15 + ["B"] * 15,
                       "v": np.random.rand(30)})
g = sns.FacetGrid(row="l", data=df)
g.map(sns.pointplot, "a", "v")
plt.show()
```
seaborn plots all the xtick labels instead of just picking a few and it looks horrible: Is there a way to customize it so that it plots every n-th tick on x-axis instead of all of them?

Response:
You have to skip x labels manually like in this example:
```
import seaborn as sns
import matplotlib.pylab as plt
import pandas
import numpy as np

df = pandas.DataFrame({"a": range(1001, 1031),
                       "l": ["A",] * 15 + ["B",] * 15,
                       "v": np.random.rand(30)})
g = sns.FacetGrid(row="l", data=df)
g.map(sns.pointplot, "a", "v")

# iterate over axes of FacetGrid
for ax in g.axes.flat:
    labels = ax.get_xticklabels() # get x labels
    for i,l in enumerate(labels):
        if(i%2 == 0): labels[i] = '' # skip even labels
    ax.set_xticklabels(labels, rotation=30) # set new labels
plt.show()
```


Question: boxplot using precalculated (summary) statistics I need to do a boxplot (in Python and matplotlib) but I do not have the original "raw" data. What I have are precalculated values for max, min, mean, median and IQR (normal distribution) but still I'd like to do a boxplot. Of course plotting outliers isn't possible, but beside that I guess all information is there. I've search all over to find an answer without success. The closest I've come is the same question but for R (which I'm unfamiliar with). See Is it possible to plot a boxplot from previously-calculated statistics easily (in R?)

Response:
Thanks to the comment of @tacaswell I was able to find the required documentation and come up with an example using Matplotlib 1.4.3. However, this example does not automatically scale the figure to the correct size.
```
import matplotlib.pyplot as plt

item = {}

item["label"] = 'box' # not required
item["mean"] = 5 # not required
item["med"] = 5.5
item["q1"] = 3.5
item["q3"] = 7.5
#item["cilo"] = 5.3 # not required
#item["cihi"] = 5.7 # not required
item["whislo"] = 2.0 # required
item["whishi"] = 8.0 # required
item["fliers"] = [] # required if showfliers=True

stats = [item]

fig, axes = plt.subplots(1, 1)
axes.bxp(stats)
axes.set_title('Default')
y_axis = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
y_values = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
plt.yticks(y_axis, y_values)
```
Relevant links to the documentation: matplotlib.axes.Axes.bxp boxplot_stats datastructure Boxplot drawer function


Question:
Turn off axis border for polar matplotlib plot I have a polar axes in matplotlib that has text which extends outside of the range of the axes. I would like to remove the border for the axis -- or set it to the color of the background so that the text is more legible. How can I do this? Simply increasing the size of the axes is not an acceptable solution (because the figure is embeddable in a GUI and it becomes too small if this is done). Changing the color of the background to be black so that the border is not visible is also not an acceptable solution. A considerable amount of code that does various parts of plotting things is omitted, but here is the generation of the figure and axes itself:
```
import pylab as pl
fig = pl.figure(figsize=(5,5), facecolor='white')
axes = pl.subplot(111, polar=True, axisbg='white')

pl.xticks([])
pl.yticks([])
pl.ylim(0,10)

# ... draw lots of things
```

Response: Just add this line: axes.spines['polar'].set_visible(False) and it should go away! eewh, all the anatomy terms.


Question:
python matplotlib update scatter plot from a function I am trying to automatically update a scatter plot. The source of my X and Y values is external, and the data is pushed automatically into my code in a non-predicted time intervals (rounds). I have only managed to plot all the data when the whole process ended, whereas I am trying to constantly add and plot data into my canvas. What I DO get (at the end of the whole run) is this: Whereas, what I am after is this: A simplified version of my code:
```
import matplotlib.pyplot as plt

def read_data():
    #This function gets the values of xAxis and yAxis
    xAxis = [some values]  #these valuers change in each run
    yAxis = [other values] #these valuers change in each run

    plt.scatter(xAxis,yAxis, label  = 'myPlot', color = 'k', s=50)
    plt.xlabel('x')
    plt.ylabel('y')
    plt.show()
```

Response:
There are several ways to animate a matplotlib plot. In the following let's look at two minimal examples using a scatter plot. (a) use interactive mode plt.ion() For an animation to take place we need an event loop. One way of getting the event loop is to use plt.ion() ("interactive on"). One then needs to first draw the figure and can then update the plot in a loop. Inside the loop, we need to draw the canvas and introduce a little pause for the window to process other events (like the mouse interactions etc.). Without this pause the window would freeze. Finally we call plt.waitforbuttonpress() to let the window stay open even after the animation has finished.
```
import matplotlib.pyplot as plt
import numpy as np

plt.ion()
fig, ax = plt.subplots()
x, y = [],[]
sc = ax.scatter(x,y)
plt.xlim(0,10)
plt.ylim(0,10)

plt.draw()
for i in range(1000):
    x.append(np.random.rand(1)*10)
    y.append(np.random.rand(1)*10)
    sc.set_offsets(np.c_[x,y])
    fig.canvas.draw_idle()
    plt.pause(0.1)

plt.waitforbuttonpress()
```
(b) using FuncAnimation Much of the above can be automated using matplotlib.animation.FuncAnimation. The FuncAnimation will take care of the loop and the redrawing and will constantly call a function (in this case animate()) after a given time interval. The animation will only start once plt.show() is called, thereby automatically running in the plot window's event loop.
```
import matplotlib.pyplot as plt
import matplotlib.animation
import numpy as np

fig, ax = plt.subplots()
x, y = [],[]
sc = ax.scatter(x,y)
plt.xlim(0,10)
plt.ylim(0,10)

def animate(i):
    x.append(np.random.rand(1)*10)
    y.append(np.random.rand(1)*10)
    sc.set_offsets(np.c_[x,y])

ani = matplotlib.animation.FuncAnimation(fig, animate,
                frames=2, interval=100, repeat=True)
plt.show()
```


Question:
How to control scientific notation in matplotlib? This is my data frame I'm trying to plot:
```py
my_dic = {'stats': {'apr': 23083904, 'may': 16786816, 'june': 26197936}}
my_df = pd.DataFrame(my_dic)
```
This is how I plot it:
```py
ax = my_df['stats'].plot(kind='bar',  legend=False)
ax.set_xlabel("Month", fontsize=12)
ax.set_ylabel("Stats", fontsize=12)
ax.ticklabel_format(useOffset=False) #AttributeError: This method only works with the ScalarFormatter.
plt.show()
```
The plot: I'd like to control the scientific notation. I tried to suppress it by this line as was suggested in other questions plt.ticklabel_format(useOffset=False) but I get this error back -
```none
AttributeError: This method only works with the ScalarFormatter
```
Ideally, I'd like to show my data in (mln).

Response:
Adding this line helps to get numbers in a plain format but with ',' which looks much nicer:
```
ax.get_yaxis().set_major_formatter(
    matplotlib.ticker.FuncFormatter(lambda x, p: format(int(x), ',')))
```
And then I can use int(x)/ to convert to million or thousand as I wish: