# Point and figure chart with matplotlib

## Question:

I’m trying to make a point and figure chart. I can get it to work printing out on the terminal but I want to graph it with matplotlib. What would be the best way of doing something like this? I was thinking scatter, but when I do this the columns are spread out too far. I would like to get something much like the chart from the link I provided where the columns are as close to one another as possible. Is there a parameter I can overwrite to force this? First time using matplotlib so please excuse me if this is trivial. Thanks.

## Answers:

No personal experience, but maybe set_view_interval() or set_data_interval() from here? I have used Matplotlib for a project, but didn’t have to play with fixing the x-axis width.

You can adjust the size of the symbols used in a scatter plot by choosing the `s`

parameter. You also will likely need to adjust the size of your figure (with figsize) or the dimensions of your axes (with add_axes). This is because the symbols for scatter are square, in display units, and the x and y axis are not automatically adjusted so that width-of-one-change = height-of-one-box.

In other words, the example you provided is a rectangular plot with the height > width, and the height and width are chosen to make the width-of-one-change == height-of-one-box.

Here’s an example of apply these techniques:

```
import matplotlib.pyplot as plt
BOX = 5
START = 365
changes = (8, -3, 4, -4, 12, -3, 7, -3, 5, -9, 3)
# one way to force dimensions is to set the figure size:
fig = plt.figure(figsize=(5, 10))
# another way is to control the axes dimensions
# for axes to have specific dimensions:
# [ x0, y0, w, h] in figure units, from 0 to 1
#ax = fig.add_axes([.15, .15, .7*.5, .7])
ax = fig.add_axes([.15, .15, .7, .7])
def sign(val):
return val / abs(val)
pointChanges = []
for chg in changes:
pointChanges += [sign(chg)] * abs(chg)
symbol = {-1:'o',
1:'x'}
chgStart = START
for ichg, chg in enumerate(changes):
x = [ichg+1] * abs(chg)
y = [chgStart + i * BOX * sign(chg) for i in range(abs(chg))]
chgStart += BOX * sign(chg) * (abs(chg)-2)
ax.scatter(x, y,
marker=symbol[sign(chg)],
s=175) #<----- control size of scatter symbol
ax.set_xlim(0, len(changes)+1)
fig.savefig('pointandfigure.png')
plt.show()
```

The method developed for each scatter plot is very hackish, but the key point is that I needed to play with the scatter `s`

parameter and the figure size to get something of the desired effect.

The resulting plot is:

Ideally, one would make a custom method modeled after the scatter method. It would create a custom `Collection`

instance that would include the x’s, o’s and month labels. It would also a) automatically adjust the axes/figure aspect or b) make asymmetric symbols. This is obviously an advanced option, intended for someone wishing to contribute, as a developer, to the Matplotlib project.

Editing the colors was the best I could.

```
chgStart = START
colors=['red','black','green','blue']
for ichg, chg in enumerate(changes):
x = [ichg+1] * abs(chg)
y = [chgStart + i * BOX * sign(chg) for i in range(abs(chg))]
chgStart += BOX * sign(chg) * (abs(chg)-2)
ax.scatter(x, y,
marker=symbol[sign(chg)],
s=175, color = colors[int(sign(chg))] ) #<----- control size of scatter symbol
```