Hi there, I'm sorry to ask such a newbie question, but I'd like to format a custom box plot and although there are numerous examples on the web and tons of docstrings in matplotlib, I'm stuck somehow. My problems center around axes / spines. In detail, my problems are:
1) I want an y-axis on the left that spans from -0.6 to 1.1, ends in an arrow, has major ticks at 0 and 1 and minor ticks at [0.1...0.9] As far as I understand, there is no option to let spines end in an arrow head, so I have to draw the myself. I get the ticks to appear at the right positions and the y-range to be as desired - however, the spine line is not drawn over the full y-range, but only where there is data in the diagram. Also, I copied the arrow annotation code blindly from an older post on this list, but do not understand how I can adapt the arrow head to appear at a data position (instead of at the corner of the Axes area). One problem is, that I get ticks on the right although that spine was disabled. 2) I want some kind of x-axis at y==0, without ticks and without arrow Using some methods on the spines, I can disable the top spine and move the bottom spine to zero. However, as with the y-axis, I cannot control from where to where the line itself is drawn. As attachments, you'll find a hand sketch of what my graph should look like and matplotlib code that goes nearly all the way. I would be very happy about a hint on how to fix the problems left. Thanks an advance, Mark [cid:ed2f1b56-2e4e-4cb3-9a9e-4b2b2388781b@exch.iais.fraunhofer.de]
<<inline: boxplot_sketch.png>>
#! /usr/bin/env python """Example code for custom box diagram 2012-06-15, mark.asb...@iais.fraunhofer.de """ import numpy from matplotlib import pylab def draw_bars(data, descriptions=None, colors=None, reverse_coords=False, position=0, axes=pylab): # if no descriptions are given, use data to annotate itself if descriptions == None: descriptions = data # if no colors are given, all boxes will be white if colors == None: colors = len(data) * ('white',) # sort data for finding y centers and drawing in right order assert numpy.all(numpy.array(data) >= 0) idx = numpy.argsort(data)[::-1] data = numpy.array(data)[idx] descriptions = numpy.array(descriptions)[idx] colors = numpy.array(colors)[idx] # reverse y-position if desired if reverse_coords: data = -data # draw boxes for top, color in zip (data, colors): axes.bar (position + 0.2, top, 0.4, color=color) # put labels on boxes tops = data.tolist() bots = data.tolist()[1:] + [0,] for top, bottom, description in zip(tops, bots, descriptions): axes.text (position + 0.4, 0.5 * (top + bottom), description, horizontalalignment='center', verticalalignment='center') def draw_dataset(dataset, titles=None, descriptions=None, colors=None, axes=pylab): # ensure data is in numpy format dataset = numpy.require(dataset, dtype=float) titles = numpy.require(titles, dtype=str) descriptions = numpy.require(descriptions, dtype=str) # draw bar by bar, separating positive from negative values position = 0 for row, descr in zip(dataset, descriptions): row_data = numpy.array(row) descr_data = numpy.array (descr) positives = numpy.array(row) > 0 draw_bars( row_data[ positives], descr_data[ positives], colors, False, position, axes) draw_bars(-row_data[-positives], descr_data[-positives], colors, True, position, axes) position += 1 # finally, but title above bars if titles != None: for position, title in enumerate(titles): axes.text (position + 0.4, 1.1, title, horizontalalignment='center', verticalalignment='center') # create new figure fig = pylab.figure() ax = fig.add_subplot(1,1,1) # plot my data datasets = [(0.8, 0.6, 0.4, -0.2), (0.7, 0.5, 0.3, -0.3)] descriptions = [('A', 'B', 'C', 'D'), ('A\'', 'B\'', 'C\'', 'D\'')] colors = ['0.3', '0.5', '0.75', '0.1'] draw_dataset(datasets, ['Some Text\nLines', 'Other Text'], descriptions, colors, ax) # use left spine and x-axis at zero ax.spines['left'].set_position('zero') ax.spines['left'].set_smart_bounds(True) ax.spines['bottom'].set_position('zero') ax.spines['bottom'].set_smart_bounds(True) ax.spines['right'].set_color('none') ax.spines['top'].set_color('none') # try to add arrow to left spine # (http://www.mailinglistarchive.com/html/matplotlib-users@lists.sourceforge.net/2011-02/msg00065.html) al = 7 # arrow length in points arrowprops=dict(clip_on=False, # plotting outside axes on purpose frac=1., # make end arrowhead the whole size of arrow headwidth=al, # in points facecolor='k') kwargs = dict( xycoords='axes fraction', textcoords='offset points', arrowprops= arrowprops, ) ax.annotate("",(0,1),xytext=(0,-al), **kwargs) # left spin arrow # format rest of figure pylab.ylabel('Rate') pylab.yticks(numpy.arange(0.0, 1.1, 0.1)) #, ['%d' % val for val in vals]) pylab.xticks([]) ax.set_ylim(-0.6, 1.4) ax.set_xlim( 0.0, 2.0) ax.set_aspect('equal') pylab.title('Diagram Title') # done pylab.show()
------------------------------------------------------------------------------ Live Security Virtual Conference Exclusive live event will cover all the ways today's security and threat landscape has changed and how IT managers can respond. Discussions will include endpoint security, mobile security and the latest in malware threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________ Matplotlib-users mailing list Matplotlib-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-users