How the generate this specific chart in Python / Matplotlib
<p>I need to plot this specific chart in Python, or at least come very close to it, see the picture. I prefer to use the Matplotlib package and I already tried to a great extend but didn't came close enough. If I need another package for this then I am ok with that. </p>

<p><a href="http://i.stack.imgur.com/dGJ64.png" rel="nofollow"><img src="http://i.stack.imgur.com/dGJ64.png" alt="enter image description here"></a></p>

<p>By searching the web (found most of the answers on this site) and a lot of trail and error I was able to generate the following chart:</p>

<p><a href="http://i.stack.imgur.com/HbfU8.png" rel="nofollow">enter image description here</a></p>

<p>These were the 3 key elements in the global construction of the chart:</p>

<ul>
<li>Using <code>axhspan</code> or <code>axvspan</code> it is easy to partition the background into different colors independently of whatever chart type is choosen.</li>
<li>Scatter plot was the chart type used for ploting the single points.</li>
<li>Adding a table at the bottom for displaying the values. I did not expect it but the table is independent of the chart and the creator of the chart is free to fill it with any data he or she desires. </li>
</ul>

<p>As you can see I came very close to my desired chart. I am open for suggestions for non-obvious refactoring. </p>

<p>Some things however are still not perfect yet:</p>

<ol>
<li>I do not display percentages yet. It is easy to do by formatting to percentages but then I 'll need to multiply everything by 100. Is there a more elegant method without the need to multiply everything by 100?</li>
<li>Can I display the scatter symbols to the legend in the table on the left just like in my chart from the question? Otherwise I might plot a legend on the right side of the chart.</li>
<li>I am struggling a bit with anti-aliasing. When using the <code>savefig</code> command I want to font to be anti aliased but the graphics not. What is the best way to do this?</li>
<li>I still have to manually plot 3 + 1 = 4 lines. One of them is the horizontal zero ax. The other 3 lines are to connect the scatter points. Is there a clever solution to avoid this? </li>
<li>Would plotly give me a better and easier way of creating the same chart?</li>
</ol>

<p>The complete code:</p>

<pre><code>import matplotlib.pyplot as plt
import numpy as np


# Given data
data = [[0.129, 0.031, 0.071],
        [0.067, -0.041, 0.012],
        [-0.013, -0.08, -0.07]]

columns = ['Apple', 'Orange', 'Banana']
rows = ['top', 'mid', 'bottom']


# This code is only necessary for the chart to look as intended on the screen
# Probably need to be removed when saving chart as a picture using the savefig 
# command
plt.figure().patch.set_facecolor('white')


# set global line color of the axes
plt.rc('axes', edgecolor='#cecece')


# partition chart background into 3 strokes of different colors
pastel_shades = ['#ffefb7', '#e6fff2', '#f5feda']

for i in range(3):
    plt.axvspan(i, i + 1, facecolor=pastel_shades[i], linewidth=0)


# (cosmetic) marker settings
markers = [('D', "#0070c0", 0),
           ('_', "#ff0000", 2),
           ('s', "#0070c0", 0)]


# Add a table at the bottom of the axes
the_table = plt.table(cellText=data, 
                      rowLabels=rows, 
                      colLabels=columns, 
                      loc='bottom', 
                      cellLoc='center')


# set fontsize and fontcolor of values in table
# adjust vertical height
# set table border color
the_table.set_fontsize(9)
the_table.scale(1.0, 1.3)

for key, cell in the_table.get_celld().items():
    cell.set_edgecolor('#cecece')
    cell._text.set_color("#595959")


# Adjust layout to make room for the table
plt.subplots_adjust(left=0.2, bottom=0.2)


# set color and fontsize of the labels at the y-ax ticks
for tl in plt.axes().get_yticklabels():
    tl.set_color("#595959")
    tl.set_fontsize(7)


# set other axes properties
plt.ylabel("Y-axis", color="#595959")
plt.tick_params(axis='y', direction='out', right='off', color='#cecece')
plt.xticks([])


# Set chart title
plt.title('Chart title', color="#595959")


# Draw horizontal zero-ax
plt.axhline(0, 0, 1, color='#cecece', zorder=1)


# draw scatter plot
plt.axes().set_xlim([0, 3])

for data_row, marker in zip(data, markers):
    x = np.array([0.5, 1.5, 2.5])
    y = np.array(data_row)
    shape, color, width = marker

    plt.scatter(x, y, 
                s=60, 
                c=color, 
                zorder=3, 
                marker=shape, 
                linewidths=width, 
                edgecolors=color)


# Draw lines connecting the scatter points
vertical_data_slice = [[r[k] for r in data] for k in range(3)]

for data_column, x in zip(vertical_data_slice, np.array([0.5, 1.5, 2.5])):
    plt.vlines(x, data_column[0], data_column[2], colors="#000000", zorder=2)


# Show chart on screen
plt.show()
</code></pre>

python matplotlib charts