Advertisement
Guest User

bevstat.py

a guest
Dec 8th, 2016
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 17.05 KB | None | 0 0
  1. #!/bin/python3.4
  2. import numpy as np
  3. from os import path
  4. from bokeh.io import curdoc
  5. from bokeh.layouts import row, column, widgetbox, layout
  6. from bokeh.models import ColumnDataSource, formatters, BoxAnnotation, BoxSelectTool, HoverTool, Span, Label
  7. from bokeh.models.widgets import Slider, PreText, RadioGroup
  8. from bokeh.plotting import figure
  9. from functools import lru_cache
  10.  
  11.  
  12. data_dir = "/home/user/bokeh/bev_daten/"
  13.  
  14. age_data_m = np.loadtxt(path.join(data_dir,"bev_daten_ch_m.csv"), dtype=int)
  15. age_data_f = np.loadtxt(path.join(data_dir,"bev_daten_ch_f.csv"), dtype=int)
  16. age_data_ma = np.loadtxt(path.join(data_dir,"bev_daten_alle_m.csv"), dtype=int)
  17. age_data_fa = np.loadtxt(path.join(data_dir,"bev_daten_alle_f.csv"), dtype=int)
  18.  
  19. prediction_data_low_m_ch = np.loadtxt(path.join(data_dir,"low_prediction_m_ch.csv"), dtype=int)
  20. prediction_data_low_f_ch = np.loadtxt(path.join(data_dir,"low_prediction_f_ch.csv"), dtype=int)
  21. prediction_data_low_m_au = np.loadtxt(path.join(data_dir,"low_prediction_m_au.csv"), dtype=int)
  22. prediction_data_low_f_au = np.loadtxt(path.join(data_dir,"low_prediction_f_au.csv"), dtype=int)
  23.  
  24. prediction_data_reference_m_ch = np.loadtxt(path.join(data_dir,"reference_prediction_m_ch.csv"), dtype=int)
  25. prediction_data_reference_f_ch = np.loadtxt(path.join(data_dir,"reference_prediction_f_ch.csv"), dtype=int)
  26. prediction_data_reference_m_au = np.loadtxt(path.join(data_dir,"reference_prediction_m_au.csv"), dtype=int)
  27. prediction_data_reference_f_au = np.loadtxt(path.join(data_dir,"reference_prediction_f_au.csv"), dtype=int)
  28.  
  29. prediction_data_high_m_ch = np.loadtxt(path.join(data_dir,"high_prediction_m_ch.csv"), dtype=int)
  30. prediction_data_high_f_ch = np.loadtxt(path.join(data_dir,"high_prediction_f_ch.csv"), dtype=int)
  31. prediction_data_high_m_au = np.loadtxt(path.join(data_dir,"high_prediction_m_au.csv"), dtype=int)
  32. prediction_data_high_f_au = np.loadtxt(path.join(data_dir,"high_prediction_f_au.csv"), dtype=int)
  33.  
  34. additional_stats = {}
  35. additional_source = {}
  36.  
  37. for key in ["historical_ch","historical_au","low_ch","low_au","ref_ch","ref_au","high_ch","high_au"]:
  38.     additional_stats[key] = np.rot90(np.fliplr(np.loadtxt(path.join(data_dir,key + ".stats"), dtype=int)))
  39.     additional_stats[key][2] *= -1
  40.     additional_stats[key][4] *= -1
  41.     #x_axis_offset = 0.75 if "au" in key else 0.25
  42.     #additional_stats[key][0] += x_axis_offset
  43.  
  44.  
  45.  
  46. age_data_ma = age_data_ma - age_data_m
  47. age_data_fa = age_data_fa - age_data_f
  48.  
  49.  
  50. #since were working without a stacked bar:
  51. age_data_m = np.loadtxt(path.join(data_dir,"bev_daten_alle_m.csv"), dtype=int)
  52. age_data_f = np.loadtxt(path.join(data_dir,"bev_daten_alle_f.csv"), dtype=int)
  53.  
  54. age_data_f *= -1
  55. age_data_fa *= -1
  56. prediction_data_low_f_ch *= -1
  57. prediction_data_low_f_au *= -1
  58. prediction_data_reference_f_ch *= -1
  59. prediction_data_reference_f_au *= -1
  60. prediction_data_high_f_ch *= -1
  61. prediction_data_high_f_au *= -1
  62.  
  63. #load initial graph data
  64. display_data_m = age_data_m[0]
  65. display_data_ma = age_data_ma[0]
  66. display_data_f = age_data_f[0]
  67. display_data_fa = age_data_fa[0]
  68.  
  69. display_stats_ch = np.hstack((additional_stats["historical_ch"],additional_stats["ref_ch"]))
  70. display_stats_au = np.hstack((additional_stats["historical_au"],additional_stats["ref_au"]))
  71.  
  72. # print(len(display_stats_au[0]),len(display_stats_ch[0]))
  73. # exit()
  74.  
  75. y = [k for k in range(101)]
  76. x_scatter = np.zeros(101)
  77. laborage_min = 18
  78. laborage_max = 67
  79. historical_years = len(age_data_m)-1
  80.  
  81.  
  82.  
  83. source_m = ColumnDataSource(data=dict(y=y, display=display_data_m))
  84. source_ma = ColumnDataSource(data=dict(y=y, display=display_data_ma))
  85. source_f = ColumnDataSource(data=dict(y=y, display=display_data_f))
  86. source_fa = ColumnDataSource(data=dict(y=y, display=display_data_fa))
  87.  
  88. source_ch_stats = ColumnDataSource(data=dict(years=display_stats_ch[0]+0.25,
  89.                                              births=display_stats_ch[1],
  90.                                              deaths=display_stats_ch[2],
  91.                                              immigration=display_stats_ch[3],
  92.                                              migration=display_stats_ch[4]))
  93.  
  94. source_au_stats = ColumnDataSource(data=dict(years=display_stats_au[0]+0.75,
  95.                                              births=display_stats_au[1],
  96.                                              deaths=display_stats_au[2],
  97.                                              immigration=display_stats_au[3],
  98.                                              migration=display_stats_au[4]))
  99.  
  100. dependency_ratio_textfield = PreText(text="", width=500)
  101. total_population_textfield = PreText(text="", width=500)
  102.  
  103. hovertool_births = HoverTool(tooltips=[("Geburtenüberschuss", "@y"),("Jahr","@x")])
  104. hovertool_migration = HoverTool(tooltips=[("Wanderungssaldo", "@y"),("Jahr","@x")])
  105.  
  106. plot = figure(plot_height=400, plot_width=600, title="Ständige Wohnbevölkerung Schweiz: 2010",
  107.               tools=["save", "box_select"],
  108.               x_range=[-85000, 85000],
  109.               y_range=[0, 101])
  110.  
  111. plot_birth = figure(plot_height=400, plot_width=600, title="Geburtenüberschuss",
  112.               tools=[hovertool_births],
  113.               x_range=[display_stats_ch[0][0],display_stats_ch[0][-1]],
  114.               y_range=[-100000, 100000])
  115.  
  116. plot_migration = figure(plot_height=400, plot_width=600, title="Wanderungssaldo",
  117.               tools=[hovertool_migration],
  118.               x_range=[display_stats_ch[0][0],display_stats_ch[0][-1]],
  119.               y_range=[-180000, 180000])
  120.  
  121.  
  122. m_plot = plot.hbar(right='display', y='y', source=source_m, line_width=6, line_alpha=0.5, color="blue", legend="Schweizer")
  123. ma_plot = plot.hbar(right='display', y='y', source=source_ma, line_width=6, line_alpha=0.5, color="red", legend="Ausländer")
  124. f_plot = plot.hbar(right='display', y='y', source=source_f, line_width=6, line_alpha=0.5, color="blue")
  125. fa_plot = plot.hbar(right='display', y='y', source=source_fa, line_width=6, line_alpha=0.5, color="red")
  126.  
  127.  
  128. plot_birth.vbar(x='years',
  129.                      top='births',
  130.                      source=source_ch_stats,
  131.                      bottom=0,
  132.                      width=0.5,
  133.                      alpha=0.1,
  134.                      color="blue")
  135. plot_birth.vbar(x='years',
  136.                      top='births',
  137.                      source=source_au_stats,
  138.                      bottom=0,
  139.                      width=0.5,
  140.                      alpha=0.1,
  141.                      color="red")
  142. plot_birth.vbar(x='years',
  143.                      top='deaths',
  144.                      source=source_ch_stats,
  145.                      bottom=0,
  146.                      width=0.5,
  147.                      alpha=0.1,
  148.                      color="blue")
  149. plot_birth.vbar(x='years',
  150.                      top='deaths',
  151.                      source=source_au_stats,
  152.                      bottom=0,
  153.                      width=0.5,
  154.                      alpha=0.1,
  155.                      color="red")
  156.  
  157. a = np.array(display_stats_ch[0])
  158.  
  159. glyph_birth_ch = plot_birth.line(x=a,
  160.                      y=display_stats_ch[1]+display_stats_ch[2],
  161.                      line_width=4,
  162.                      color="blue",
  163.                      legend="Geburtenüberschuss (Schweizer)")
  164.  
  165. glyph_birth_au = plot_birth.line(x=a,
  166.                      y=display_stats_au[1]+display_stats_au[2],
  167.                      line_width=4,
  168.                      color="red",
  169.                      legend="Geburtenüberschuss (Ausländer)")
  170.  
  171. hovertool_births.renderers.append(glyph_birth_ch)
  172. hovertool_births.renderers.append(glyph_birth_au)
  173.  
  174.  
  175. plot_migration.vbar(x='years',
  176.                      top='migration',
  177.                      source=source_ch_stats,
  178.                      bottom=0,
  179.                      width=0.5,
  180.                      alpha=0.1,
  181.                      color="blue")
  182.  
  183. plot_migration.vbar(x='years',
  184.                      top='migration',
  185.                      source=source_au_stats,
  186.                      bottom=0,
  187.                      width=0.5,
  188.                      alpha=0.1,
  189.                      color="red")
  190.  
  191. plot_migration.vbar(x='years',
  192.                      top='immigration',
  193.                      source=source_ch_stats,
  194.                      bottom=0,
  195.                      width=0.5,
  196.                      alpha=0.1,
  197.                      color="blue")
  198.  
  199. plot_migration.vbar(x='years',
  200.                      top='immigration',
  201.                      source=source_au_stats,
  202.                      bottom=0,
  203.                      width=0.5,
  204.                      alpha=0.1,
  205.                      color="red")
  206.  
  207. #plot doesn't seem to work without this
  208. a = np.array(display_stats_ch[0])
  209.  
  210. glyph_migration_ch = plot_migration.line(x=a,
  211.                      y=display_stats_ch[3]+display_stats_ch[4],
  212.                      line_width=4,
  213.                      color="blue",
  214.                      legend="Migrationssaldo (Schweizer)")
  215.  
  216. glyph_migration_au = plot_migration.line(x=a,
  217.                      y=display_stats_au[3]+display_stats_au[4],
  218.                      line_width=4,
  219.                      color="red",
  220.                      legend="Migrationssaldo (Ausländer)")
  221.  
  222. hovertool_migration.renderers.append(glyph_migration_ch)
  223. hovertool_migration.renderers.append(glyph_migration_au)
  224.  
  225. #only scatterplots can be selectec with boxselect
  226. #invisible scatter along x=0
  227. scatter = plot.scatter(x=x_scatter, y=y, size=0, fill_color="red")
  228.  
  229. plot.legend.location = "top_right"
  230. plot_birth.legend.location = "bottom_left"
  231. plot_migration.legend.location = "bottom_left"
  232.  
  233. jugend_box = BoxAnnotation(top=laborage_min, fill_alpha=0.1, fill_color='red')
  234. arbeiter_box = BoxAnnotation(bottom=laborage_min, top=laborage_max, fill_alpha=0.1, fill_color='green')
  235. rentner_box = BoxAnnotation(bottom=laborage_max, fill_alpha=0.1, fill_color='red')
  236. current_year_births_box = BoxAnnotation(left=1971, right=1972, fill_alpha=0.2, fill_color='yellow')
  237. current_year_migration_box = BoxAnnotation(left=1971, right=1972, fill_alpha=0.2, fill_color='yellow')
  238.  
  239. m_f_separator = Span(location=0, dimension='height', line_dash='dashed', line_color='black', line_width=1)
  240.  
  241. annotation_female = Label(x=85, y=35, x_units='screen', y_units='screen',
  242.                  text='Weiblich', render_mode='css',
  243.                  border_line_color='black', border_line_alpha=0.4,
  244.                  background_fill_color='white', background_fill_alpha=0.7)
  245.  
  246. annotation_male = Label(x=495, y=35, x_units='screen', y_units='screen',
  247.                  text='Männlich', render_mode='css',
  248.                  border_line_color='black', border_line_alpha=0.4,
  249.                  background_fill_color='white', background_fill_alpha=0.7)
  250.  
  251. plot.yaxis.axis_label = "Alter"
  252. plot.xaxis.formatter = formatters.NumeralTickFormatter(format="(0,0)")
  253.  
  254. plot_birth.yaxis.axis_label = "Todesfälle (-)  Geburten (+)"
  255. plot_birth.yaxis.formatter = formatters.PrintfTickFormatter(format="%d")
  256. plot_birth.xgrid.minor_grid_line_alpha = 0.5
  257.  
  258. plot_migration.yaxis.axis_label = "Auswanderung (-)  Einwanderung (+)"
  259. plot_migration.yaxis.formatter = formatters.PrintfTickFormatter(format="%d")
  260. plot_migration.xgrid.minor_grid_line_alpha = 0.5
  261.  
  262. offset = Slider(title="", value=0, start=0, end=44+30, step=1,
  263.                 callback_throttle=15000000, callback_policy="throttle",
  264.         sizing_mode="scale_height", orientation="horizontal")
  265.  
  266.  
  267. prediction_radio_group = RadioGroup(
  268.         labels=["Szenario: \"Tief\"", "Referenzszenario", "Szenario: \"Hoch\""], active=1)
  269.  
  270. def update_stat_plots(_):
  271.     for stat, num in [('births',1),('deaths',2),('immigration',3),('migration',4)]:
  272.         if prediction_radio_group.active == 0:
  273.             source_ch_stats.data[stat] = np.hstack((additional_stats["historical_ch"][num], additional_stats["low_ch"][num]))
  274.             source_au_stats.data[stat] = np.hstack((additional_stats["historical_au"][num], additional_stats["low_au"][num]))
  275.         if prediction_radio_group.active == 1:
  276.             source_ch_stats.data[stat] = np.hstack((additional_stats["historical_ch"][num], additional_stats["ref_ch"][num]))
  277.             source_au_stats.data[stat] = np.hstack((additional_stats["historical_au"][num], additional_stats["ref_au"][num]))
  278.         if prediction_radio_group.active == 2:
  279.             source_ch_stats.data[stat] = np.hstack((additional_stats["historical_ch"][num], additional_stats["high_ch"][num]))
  280.             source_au_stats.data[stat] = np.hstack((additional_stats["historical_au"][num], additional_stats["high_au"][num]))
  281.  
  282.         update_data(None, None, offset.value)
  283.  
  284. def update_dependency_box(attr, old, new):
  285.     global laborage_max, laborage_min
  286.     laborage_max = max(new['1d']['indices'])
  287.     laborage_min = min(new['1d']['indices'])
  288.     jugend_box.update(top=laborage_min)
  289.     arbeiter_box.update(bottom=laborage_min, top=laborage_max)
  290.     rentner_box.update(bottom=laborage_max)
  291.     update_dependency_text()
  292.  
  293. def update_dependency_text():
  294.     display_data_total = source_m.data['display'] + (-1*source_f.data['display'])
  295.     dependency_ratio_textfield.update(text="Abhängigenquotient: {dependency_ratio:.2f} \n"
  296.                                            "\t- Jugendquotient: {dependency_ratio_minor:.2f} bei Eintrittsalter: {working_age}\n"
  297.                                            "\t- Altersquotient: {dependency_ratio_major:.2f} bei Rentenalter: {retirement_age}".format(
  298.         retirement_age=laborage_max,
  299.         working_age=laborage_min,
  300.         dependency_ratio=(sum(display_data_total[0:laborage_min])+sum(display_data_total[laborage_max:]))/sum(display_data_total[laborage_min:laborage_max]),
  301.         dependency_ratio_minor=(sum(display_data_total[0:laborage_min]))/sum(display_data_total[laborage_min:]),
  302.         dependency_ratio_major=(sum(display_data_total[laborage_max:]))/sum(display_data_total[:laborage_max])))
  303.  
  304. def update_population_text():
  305.     source_m_sum = sum(source_m.data['display'])
  306.     source_ma_sum = sum(source_ma.data['display'])
  307.     source_f_sum = sum(source_f.data['display']) * -1
  308.     source_fa_sum = sum(source_fa.data['display']) * -1
  309.  
  310.     total_population_textfield.update(text="Gesamtbevölkerung: {total_pop:,}\n"
  311.                                            "\t- Männlich: {total_pop_m:,}\n"
  312.                                            "\t\t- Schweizer: {total_pop_m_ch:,}\n"
  313.                                            "\t\t- Ausländer: {total_pop_m_au:,}\n"
  314.                                            "\t- Weiblich: {total_pop_f:,}\n"
  315.                                            "\t\t- Schweizerinnen: {total_pop_f_ch:,}\n"
  316.                                            "\t\t- Ausländerinnen: {total_pop_f_au:,}".format(
  317.         total_pop=source_m_sum + source_f_sum,
  318.         total_pop_m=source_m_sum,
  319.         total_pop_m_ch=source_m_sum - source_ma_sum,
  320.         total_pop_m_au=source_ma_sum,
  321.         total_pop_f=source_f_sum,
  322.         total_pop_f_ch=source_f_sum - source_fa_sum,
  323.         total_pop_f_au=source_fa_sum))
  324.  
  325. def get_new_display_data(slider):
  326.     if slider <= historical_years:
  327.         return (age_data_m[slider],age_data_ma[slider],age_data_f[slider],age_data_fa[slider])
  328.     elif slider > historical_years and prediction_radio_group.active == 0:
  329.         slider -= historical_years+1
  330.         return (prediction_data_low_m_ch[slider],prediction_data_low_m_au[slider],prediction_data_low_f_ch[slider],prediction_data_low_f_au[slider])
  331.     elif slider > historical_years and prediction_radio_group.active == 1:
  332.         slider -= historical_years+1
  333.         return (prediction_data_reference_m_ch[slider],prediction_data_reference_m_au[slider],prediction_data_reference_f_ch[slider],prediction_data_reference_f_au[slider])
  334.     elif slider > historical_years and prediction_radio_group.active == 2:
  335.         slider -= historical_years+1
  336.         return (prediction_data_high_m_ch[slider],prediction_data_high_m_au[slider],prediction_data_high_f_ch[slider],prediction_data_high_f_au[slider])
  337.  
  338. def update_current_year_box(slider):
  339.     current_year_births_box.update(left=1971+slider-1,right=1971+slider)
  340.     current_year_migration_box.update(left=1971+slider-1,right=1971+slider)
  341.  
  342. def update_data(attrname, old, new):
  343.     source_m.data['display'], source_ma.data['display'], source_f.data['display'], source_fa.data['display'] = get_new_display_data(new)
  344.     update_population_text()
  345.     update_dependency_text()
  346.     update_current_year_box(new)
  347.     plot.title.text = "Ständige Wohnbevölkerung: {}".format(str(1971+new))
  348.  
  349.  
  350. update_dependency_text()
  351. update_population_text()
  352.  
  353. offset.on_change('value', update_data)
  354. prediction_radio_group.on_click(update_stat_plots)
  355. scatter.data_source.on_change('selected', update_dependency_box)
  356.  
  357. inputs = widgetbox(dependency_ratio_textfield, total_population_textfield, prediction_radio_group, width=600)
  358.  
  359. curdoc().add_root(column(row(plot, column(inputs,offset)), row(plot_birth, plot_migration)))
  360. curdoc().title = "Wohnbevölkerung der Schweiz, Aufteilung nach Alter und Geschlecht"
  361.  
  362.  
  363. for my_plot in [plot, plot_birth, plot_migration]:
  364.     my_plot.toolbar.logo = None
  365.  
  366. for my_layout in [jugend_box, arbeiter_box, rentner_box, m_f_separator, annotation_male, annotation_female]:
  367.     plot.add_layout(my_layout)
  368.  
  369. plot_birth.add_layout(current_year_births_box)
  370. plot_migration.add_layout(current_year_migration_box)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement