I'm having some issues with assigning my own x and y values for a plot. By default, x and y are combinations of data frame column names.
For example, var_combinations contains:
(('Cerebrum Volume', 'Cerebellum Volume'), ('Cerebrum Volume', 'Cerebellum Surface Area'), ('Cerebellum Volume', 'Cerebellum Surface Area'))
This works great when left alone, see working code below.
col_names = [list(data.columns)[4], list(data.columns)[3], list(data.columns)[1]]
var_combinations = tuple(itertools.combinations(col_names, 2))
def create_plot(xy=var_combinations, logged=False):
if not logged:
fig1, axs1 = plt.subplots(1, (len(xy)), figsize=(16, 5))
for i, (x, y) in enumerate(xy):
axs1[i].scatter(data[x], data[y], c=taxon.map(colors), edgecolor='k')
axs1[i].set(
title=f'Primate {xy[i][0]} against\n{xy[i][1]}',
xlabel=f'{xy[i][0]}',
ylabel=f'{xy[i][1]}'
)
elif logged: .........
create_plot(var_combinations, logged=False)
However I want to be able to enter my own variable names when calling the function, such as:
create_plot(('Cerebellum Surface Area', 'Cerebrum Volume'), ('etc', 'etc'))
When calling this way I get a ValueError: too many values to unpack (expected 2)
when I hit the for loop. How do I fix this problem (and make sure the title/axes labelling and figure plotting works fine)?
Sample data from csv:
Species ,CerebellumSurfaceArea,CerebrumSurfaceArea,CerebellumVolume ,CerebrumVolume,Source,Taxon,,,,,,
Homo_sapiens,,,111.4,1088,MacLeod et al. (2003),Hominidae,,,,,,
Homo_sapiens,,,138.6,1387.1,,Hominidae,,,,,,
Homo_sapiens,,,132,1176.6,,Hominidae,,,,,,
Homo_sapiens,,,139.8,1264.5,,Hominidae,,,,,,
Homo_sapiens,1590,2038,,,Sereno et al. (2020),Hominidae,,,,,,
Homo_sapiens,1128,,,,Sultan and Braitenberg (1993),Hominidae,,,,,,
Pan_troglodytes,345.545,,52.1,383.22,Ashwell (2020),Hominidae,,,,,,
Pan_troglodytes,,,50.1,343.8,MacLeod et al. (2003),Hominidae,,,,,,
CodePudding user response:
- There are two issues, and they only occur when trying to send a single
tuple
to the function.xy
should be atuple
oftuples
- It should be similar to
(('CerebrumVolume', 'CerebellumVolume '), ('CerebrumVolume', 'CerebellumSurfaceArea'), ('CerebellumVolume ', 'CerebellumSurfaceArea'))
- You are giving it
('Cerebellum Surface Area', 'Cerebrum Volume')
which is not correctly unpacked. xy=(('CerebrumVolume', 'CerebellumVolume '),)
works for sending a singletuple
to the function.
- It should be similar to
- When there is only one set of tuples to unpack,
plt.subplots
creates a singleaxes
instead of an array ofaxes
- Use
squeeze=False
so there will always be an array, even if there is only oneaxes
, and then flatten the array withaxes.flatten()
.
- Use
def create_plot(xy=var_combinations, logged=False):
if not logged:
fig1, axs1 = plt.subplots(1, (len(xy)), figsize=(16, 5), squeeze=False) # updated with squeeze=False
axs1 = axs1.flatten() # added
for i, (x, y) in enumerate(xy):
axs1[i].scatter(data[x], data[y], c=data.Taxon.map(colors), edgecolor='k')
axs1[i].set(
title=f'Primate {xy[i][0]} against\n{xy[i][1]}',
xlabel=f'{xy[i][0]}',
ylabel=f'{xy[i][1]}'
)
data = pd.read_csv('data.csv', usecols=range(7))
col_names = data.columns.to_numpy()[[4, 3, 1]]
var_combinations = tuple(itertools.combinations(col_names, 2))
colors = {'Hominidae': 'tab:green'}
# fix the way a single tuple is passed to the function
create_plot(xy=(('CerebrumVolume', 'CerebellumVolume '),))