0

I have an NLTK function that creates a AxesSubplot like this:

# Names ending letters frequency
import nltk
import matplotlib.pyplot as plt

cfd = nltk.ConditionalFreqDist(
    (fileid, name[-1]) 
    for fileid in names.fileids()
    for name in names.words(fileid))

plt.figure(figsize=(12, 6)) 

cfd.plot()

cfd_graph

And I would like to change the colors of the lines individually. Most solutions I see online generate each line individually with a separate plot line. However the matplotlib .plot() method is called within the ConditionalFreqDist .plot(). Is there an alternative way I can change the colors of the lines? I'd like the female line to be blue and the male line to be green.

  • check this: https://stackoverflow.com/questions/4805048/how-to-get-different-colored-lines-for-different-plots-in-a-single-figure the solutions suggested there will work for either – Roim Sep 30 '20 at 19:43
  • Does this answer your question? [How to get different colored lines for different plots in a single figure?](https://stackoverflow.com/questions/4805048/how-to-get-different-colored-lines-for-different-plots-in-a-single-figure) – Roim Sep 30 '20 at 19:43
  • @Roim When using the `.set_color_cycle method`, I get an error: `AttributeError: 'AxesSubplot' object has no attribute 'set_color_cycle'` – Robert Hensley Sep 30 '20 at 21:05
  • @Roim the `.set_prop_cycle` method words, but I can't specify the colors – Robert Hensley Sep 30 '20 at 21:09

2 Answers2

1

NLTK's ConditionalFreqDist.plot method returns a plain matplotlib axes object as you can see here. From this, you can get the lines directly using ax.lines and set the colors using set_color.

I don't have NLTK installed now so I'll just make the axes directly, plot a red and a blue line, and turn these to black and green.

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 15, 21)
y0 = 0.6*np.sin(x)
y1 = np.sin(1.2 + 0.5*x)

fig, ax = plt.subplots(1,1)
ax.plot(x, y0, 'r')
ax.plot(x, y1, 'b')
# this is where ConditionalFreqDist will return the axes

# these are the lines you would write
ax.lines[0].set_color('k')
ax.lines[1].set_color('g')

enter image description here

Specifically, for the OP's case it should look like:

import nltk
import matplotlib.pyplot as plt

cfd = nltk.ConditionalFreqDist(
    (fileid, name[-1]) 
    for fileid in names.fileids()
    for name in names.words(fileid))

plt.figure(figsize=(12, 6)) 

ax = cfd.plot()

ax.lines[0].set_color('k')
ax.lines[1].set_color('g')
tom10
  • 67,082
  • 10
  • 127
  • 137
  • I put the line `fig, ax = plt.subplots(1,1)` before `cfd.plot()`, but when looking at `ax.lines` after I have an empty list. – Robert Hensley Oct 01 '20 at 23:49
  • 1
    @RobertHensley: The `fig, ax`, etc was just to get what you get back from `cfd.plot()`. What you should do is `ax = cfd.plot()`, where `ax =` is an edit so you can get `ax` from `cfd.plot` in your original first code example, and then, do my last two lines, `ax.lines[0].set_color('k')`, etc. – tom10 Oct 02 '20 at 00:05
  • When I save `ax = cfd.plot()`, I am able to see the list of line objects. But after doing the `ax.lines[0].set_color('k')` lines following `ax = cfd.plot()`, the graph's colors remain the same for some reason. However I found a solution using the axis functions you mentioned, although it's a bit messy. – Robert Hensley Oct 02 '20 at 00:16
  • 1
    @RobertHensley: for creating the figure and axes, I've appended the code I think is the most consistent with NLTK and your initial code (I should have done this full code example instead of including code in my earlier comment). I'm not sure about the colors names... certainly `'k'` and `'g'` are valid matplotlib color names, but it seems to be taking the [CSS style names](https://matplotlib.org/3.1.0/gallery/color/named_colors.html) though I don't know why only the CSS names would work. – tom10 Oct 02 '20 at 01:10
  • matplotlib color names isn't the issue; they work in the solution below as well. It's just for some reason the saved `ax` variable isn't updating the graph that's displayed, but saving the figure of it and making the color changes seems to work – Robert Hensley Oct 02 '20 at 02:42
0

This ended up working, using the suggestions from @tom10 :

import nltk
import matplotlib.pyplot as plt

cfd = nltk.ConditionalFreqDist(
    (fileid, name[-1]) 
    for fileid in names.fileids()
    for name in names.words(fileid))

fig, ax = plt.subplots(1,1)

cfd.plot()

ax.lines[0].set_color('blue')
ax.lines[1].set_color('green')

fig.set_size_inches(10, 4)

fig

enter image description here