Who’s up for open access?

by Lucas Wilkins

Looking through the recent petition/vow making against the commercial nature of academic journals (http://thecostofknowledge.com/) I couldn’t help notice a fairly strong subject area bias. So, I scraped the subject area fields of the website and made this pretty graph:

But what does it mean?

If you want to make your own jelly plot, here’s the python class to do it. You’ll need this image too (click for full size):

It’s a little slow at the moment, but it works.


from numpy import *
import Image
import colorsys

def plot_fracs_on(plt, fracs, color=[1,1,1], linewidth=3, scales=(1,1)):
    for frac in fracs:
            [scales[0]*0.5, scales[0]*(0.5-0.5*cos(2*pi*frac))],
            [scales[1]*0.5, scales[1]*(0.5-0.5*sin(2*pi*frac))],
            color=color, linewidth=linewidth)

# vectorise the colorsys components
to_hsv = vectorize(colorsys.rgb_to_hsv)
to_rgb = vectorize(colorsys.hsv_to_rgb)

# binning function for making pie chart
def pie_binner(data):
    """ Create a function to assign a class to each number in [0,1] according to data"""
    # sort data
    pairs = data.items()

    pairs.sort(cmp = lambda x,y: cmp(x[1],y[1]))

    labels, vals = zip(*pairs)

    # fractional amounts
    total = float(sum(vals))
    fracs = [val/total for val in vals]

    # cumulative fractions
    nfracs = len(fracs)
    cum_fracs = [sum(fracs[:i+1]) for i in range(nfracs)]

    # create function
    def bin_function(value):
        """ Expects a number in [0,1] """
        for i in range(nfracs):
            if value > cum_fracs[i] :
                return nfracs - i
        return 0

    # return function, labels and fractions
    return bin_function, labels, fracs, cum_fracs

class JellyPlot:
    """ Plots that invlove a jelly """
    def __init__(self, filename="piejelly.png"):
        print "Loading data, man this is slow..."
        fid = open(filename)
        image = Image.open(fid)

        data = array(image.getdata()).reshape(image.size[0], image.size[1], 4)

        # discard alpha channel

        rgbdata = data[:,:,:3]

        # get matrix of hsv values

        # creates tuple of np arrays in [0,1]
        rgbdata = rgbdata/256.

        hsvdata = list(to_hsv(rgbdata[:,:,0], rgbdata[:,:,1], rgbdata[:,:,2]))
        s = (hsvdata[2].shape[1], hsvdata[2].shape[0])

        # set fields, ridiculous reshaping
        self.hsvdata = [x.reshape(*s) for x in hsvdata]
        self.newhsvdata = self.hsvdata
        self.shape = s
        self.legend = None
        self.cfracs = None
        self.figsize = image.size[0], image.size[1]
        print "Done."

    def __apply_hue_transform__(self, transform):
        """ Internal thing for transforming the hue coordinate """
        self.newhsvdata[0] = (self.hsvdata[0]+transform)%1

    def make_stripy(self):
        """ Just for fun (and testing) """
            (1./jellyplot.shape[0])*arange(jellyplot.shape[0]).reshape(-1,1) +

    def pie(self, data, hue_offset=0.3):
        """ makes a jellypie chart for a dictionary """
        assert data.__class__ == dict

        # find centre of image
        cx, cy = self.shape[0]/2., self.shape[1]/2.

        # matrix of angles
        xcoord = (arange(self.shape[0]).reshape(-1,1)-cx)
        ycoord = (arange(self.shape[1]).reshape(1,-1)-cy)
        angles = 0.5-arctan2(xcoord,ycoord)/(2*pi)

        # create transformation
        binner_fun, labels, fracs, cfracs = pie_binner(data)

        binner_fun_v = vectorize(binner_fun)

        print "Calculating transformation: this isn't optimised so may take a while..."
        pie_data_transform = hue_offset+binner_fun_v(angles)/float(len(data))

        print "Applying..."


        # create legend data

        self.legend = [(("%3.0d%%: "%(100*f))+lab,
                            hue_offset + i/float(len(data)), 1., 0.5))
                       for f,lab,i in zip(fracs,labels,range(len(data)))]
        self.cfracs = cfracs

    def show(self, legend_offset=2):
        """ Show the chart, legend_offset increases the hight of the legend by n entries - default=2 """
        import matplotlib.pyplot as plt

        dpi = plt.rcParams['figure.dpi']
        fs = self.figsize[0]/dpi, self.figsize[1]/dpi
        k = 0.01
        ax1 = plt.axes([k,1./6,2./3,2./3], frameon=False)

        newimage = Image.fromarray(self.__create_rgb_data__())
        im = ax1.imshow(newimage, origin="lower")
        if not self.cfracs == None:
            plot_fracs_on(ax1, self.cfracs, scales=self.shape)

        if not self.legend == None:
            ax2 = plt.axes([2./3+k,0,1./3-k,1],frameon=False)

            dx = 0.05
            k_txt = 0.03
            x = 0.5*(1-dx*(len(self.legend)-legend_offset))

            for leg,col in self.legend:
                x += dx

    def __create_rgb_data__(self):
        print "Rendering..."
        return uint8(256*array(to_rgb(*self.newhsvdata)).swapaxes(0,2).swapaxes(0,1))

    def imshow(self):
        """ Show the plot as an image"""
        rgbdata = self.__create_rgb_data__()

        # convert back to image
        newimage = Image.fromarray(rgbdata)

if __name__ == "__main__":
    jellyplot = JellyPlot()             # make a plot object
    jellyplot.pie({"A":4,"B":2,"C":3})  # turn it into a pie chart
    jellyplot.show()                    # show it
About these ads

3 Comments to “Who’s up for open access?”

  1. Very pretty. But what do you think the reason is for this? Are mathematicians being ripped off the most, or do they just feel more strongly about the issue? Or (probably most likely) has the petition just done the rounds on the mathematicians’ mailing lists more than those of the other communities?

    • We’ll my argument was going to be that they have a subject which is well defined. There is far less need to communicate fuzzy concepts. As such there is far less need for authority than in the ‘softer’ sciences where communication relies far more heavily on established modes of explanation. ‘Soft’ sciences are more normative, with far more things just being done how they are done, and accepted as given. There is an ‘if its not in X or Y it’s probably not very useful’ attitude. – not because they expect it to be good or bad per se, but because it takes so fucking long to work out what other people are saying that there isn’t enough time to deal with people who buck trends or refuse to present a theory in a tailor made box with a bow on it – plus they’re usually spending time doing experiments. To a biologist, it’s more trouble than it’s worth to go against the grain, it’s hard enough getting people to listen as it is – open access wont help that, in fact, unless every switches all at once, removing the establishment is only going to make things harder. Mathematicians have far less to lose because they rely on convention far less.

      So there a more pro establishment feeling in the ‘softer’ sciences, probably a justified feeling too. Social and biological sciences don’t really respect the whole socially dysfunctional maverick archetype. Their ideals are cooperative but conservative. Mathematics and physics are very macho, people go off on their own and work stuff out more and the lone mad theorist is accepted and even idolised – they are individualistic and radical in their ideals.

      Anyway, I didn’t write this before because I wasn’t completely of it convinced myself. But as you asked ;)

      • That makes a certain amount of sense, though as you say it’s hard to know for sure if that’s the reason. I guess the relatively low percentage of physicists could be explained by the fact that they’re already a long way towards ditching the commercial publishers altogether, since at least in theoretical physics it seems to be acceptable to just publish for free on arXiv instead.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Get every new post delivered to your Inbox.

Join 483 other followers

%d bloggers like this: