One issue for Periodic Table of Elements
DustinChen1986 opened this issue · 1 comments
Hi, I follow the example to draw a Periodic Table of Elements.
My code first is as follows:
import pandas as pd
import numpy as np
from plotnine import *
elements = pd.read_csv('elements.csv', encoding='gbk')
elements['group'] = [-1 if g == '-' else int(g) for g in elements.group]
elements['bonding type'] = elements['bonding type'].astype('category')
elements['Metal'] = elements['Metal'].astype('category')
elements['atomic_number'] = elements['atomic number'].astype(str)
top = elements.query('group != -1').copy()
bottom = elements.query('group == -1').copy()
top['x'] = top.group
top['y'] = top.period
nrows = 2
hshift = 3.5
vshift = 3
bottom['x'] = np.tile(np.arange(len(bottom)//nrows), nrows) + hshift
bottom['y'] = bottom.period + vshift
tile_width = 0.95
tile_height = 0.95
def inner_text(data):
layers = [geom_text(data, aes(label='atomic_number'), nudge_x=-0.40, nudge_y=0.40,
ha='left', va='top', fontweight='normal', size=6),
geom_text(data, aes(label='symbol'), nudge_y=.1, size=9),
geom_text(data, aes(label='name'), nudge_y=-0.125, fontweight='normal', size=4.5),
geom_text(data, aes(label='atomic mass'), nudge_y=-.3, fontweight='normal', size=4.5)]
return layers
split_df = pd.DataFrame({
'x': 3-tile_width/4,
'y': [6, 7],
'Metal': pd.Categorical(['lanthanoid', 'actinoid'])
})
groupdf = top.groupby(
'group'
).agg(
y=('period', np.min)
).reset_index()
plot = (ggplot(aes('x', 'y'))
+ aes(fill='Metal')
+ geom_tile(top, aes(width=tile_width, height=tile_height))
+ geom_tile(split_df, aes(width=tile_width/2, height=tile_height))
+ geom_tile(bottom, aes(width=tile_width, height=tile_height))
+ inner_text(top)
+ inner_text(bottom)
+ geom_text(groupdf, aes('group', 'y', label='group'),
color='gray', nudge_y=.525,
va='bottom', fontweight='normal', size=9,
inherit_aes=False
)
+ scale_y_reverse(breaks=range(1, 8),
limits=(0, 10.5)
)
+ scale_fill_brewer(type='qual', palette=3)
+ coord_equal(expand=False)
+ theme_void()
+ theme(figure_size=(12, 6),
plot_background=element_rect(fill='white'),
axis_text_y=element_text(margin={'r':5}, color='gray',
size=9)
)
)
plot.save('元素周期表.pdf', height=6, width=10)
This code successfully drew a Periodic Table.
But when I add a code at ggplot (text=element_text(family="Times New Roman")):
import pandas as pd
import numpy as np
from plotnine import *
elements = pd.read_csv('elements.csv', encoding='gbk')
elements['group'] = [-1 if g == '-' else int(g) for g in elements.group]
elements['bonding type'] = elements['bonding type'].astype('category')
elements['Metal'] = elements['Metal'].astype('category')
elements['atomic_number'] = elements['atomic number'].astype(str)
top = elements.query('group != -1').copy()
bottom = elements.query('group == -1').copy()
top['x'] = top.group
top['y'] = top.period
nrows = 2
hshift = 3.5
vshift = 3
bottom['x'] = np.tile(np.arange(len(bottom)//nrows), nrows) + hshift
bottom['y'] = bottom.period + vshift
tile_width = 0.95
tile_height = 0.95
def inner_text(data):
layers = [geom_text(data, aes(label='atomic_number'), nudge_x=-0.40, nudge_y=0.40,
ha='left', va='top', fontweight='normal', size=6),
geom_text(data, aes(label='symbol'), nudge_y=.1, size=9),
geom_text(data, aes(label='name'), nudge_y=-0.125, fontweight='normal', size=4.5),
geom_text(data, aes(label='atomic mass'), nudge_y=-.3, fontweight='normal', size=4.5)]
return layers
split_df = pd.DataFrame({
'x': 3-tile_width/4,
'y': [6, 7],
'Metal': pd.Categorical(['lanthanoid', 'actinoid'])
})
groupdf = top.groupby(
'group'
).agg(
y=('period', np.min)
).reset_index()
plot = (ggplot(aes('x', 'y'))
+ aes(fill='Metal')
+ geom_tile(top, aes(width=tile_width, height=tile_height))
+ geom_tile(split_df, aes(width=tile_width/2, height=tile_height))
+ geom_tile(bottom, aes(width=tile_width, height=tile_height))
+ inner_text(top)
+ inner_text(bottom)
+ geom_text(groupdf, aes('group', 'y', label='group'),
color='gray', nudge_y=.525,
va='bottom', fontweight='normal', size=9,
inherit_aes=False
)
+ scale_y_reverse(breaks=range(1, 8),
limits=(0, 10.5)
)
+ scale_fill_brewer(type='qual', palette=3)
+ coord_equal(expand=False)
+ theme_void()
+ theme(text=element_text(family="Times New Roman"), # I add one code here
figure_size=(12, 6),
plot_background=element_rect(fill='white'),
axis_text_y=element_text(margin={'r':5}, color='gray',
size=9)
)
)
plot.save('elements.pdf', height=6, width=10)
Sorry for the late reply, I just saw this issue.
Previous all text elements are blank i.e. text=element_blank()
, so they do not show when you change that it affects all other elements which take on default values. The solution to then blank out each of the other elements that you don't want. i.e. axis_text_x=element_blank(), ...