show_amplitude_echart.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. import streamlit as st
  2. import numpy as np
  3. from streamlit_echarts import st_echarts, JsCode
  4. # So that you can choose an interval of points on which we apply q-calc algorithm
  5. def plot_interact_abs_from_f(f, r, i):
  6. # for making it work smoothly with streamlit
  7. if 'start' not in st.session_state or 'end' not in st.session_state:
  8. st.session_state.start = 0
  9. st.session_state.end = 100
  10. if 'legendselection' not in st.session_state:
  11. st.session_state.legendselection = '|S|'
  12. # data
  13. s = np.abs(np.array(r) + 1j * np.array(i))
  14. abs_S = list(s)
  15. # case (s[x] = 0) => (log10(s[x]) = log10(min(s)))
  16. m = np.min(np.where(s == 0, np.inf, s))
  17. db_abs_S = list(20 * np.where(s == 0, np.log10(m), np.log10(s)))
  18. # echarts for datazoom https://discuss.streamlit.io/t/streamlit-echarts/3655
  19. # datazoom https://echarts.apache.org/examples/en/editor.html?c=line-draggable&lang=ts
  20. # axis pointer values https://echarts.apache.org/en/option.html#axisPointer
  21. options = {
  22. "legend": {
  23. "data": ['|S|', '|S| (dB)'],
  24. "selectedMode": "single",
  25. "selected": {
  26. '|S|': st.session_state.legendselection == '|S|',
  27. '|S| (dB)': st.session_state.legendselection == '|S| (dB)'
  28. }
  29. },
  30. "xAxis": {
  31. "type": "category",
  32. "data": f,
  33. "name": "Hz",
  34. "nameTextStyle": {
  35. "fontSize": 16
  36. },
  37. "axisLabel": {
  38. "fontSize":
  39. 16,
  40. "formatter":
  41. JsCode(
  42. "function(x){return Intl.NumberFormat('en-US').format(x).replaceAll(',',\"_\")}"
  43. ).js_code
  44. },
  45. "axisPointer": {
  46. "label": {
  47. "formatter":
  48. JsCode(
  49. "function(x){return Intl.NumberFormat('en-US').format(x.value).replaceAll(',',\"_\")}"
  50. ).js_code
  51. }
  52. }
  53. },
  54. "yAxis": {
  55. "type": "value",
  56. "axisLabel": {
  57. "fontSize": 16,
  58. },
  59. },
  60. "series": [{
  61. "name": "|S|",
  62. "data": abs_S,
  63. "type": "line",
  64. }, {
  65. "name": "|S| (dB)",
  66. "data": db_abs_S,
  67. "type": "line",
  68. }],
  69. "height":
  70. 300,
  71. "dataZoom": [{
  72. "type": "slider",
  73. "start": st.session_state.start,
  74. "end": st.session_state.end,
  75. "height": 100,
  76. "bottom": 10
  77. }],
  78. "tooltip": {
  79. "trigger":
  80. "axis",
  81. "axisPointer": {
  82. "type": 'cross',
  83. "label": {
  84. "show": "true",
  85. }
  86. },
  87. "formatter":
  88. JsCode("function(x){\
  89. return \"frequency: \" + Intl.NumberFormat('en-US').format(x[0].name).replaceAll(',',\"_\")\
  90. + \" Hz<br>\" + x[0].seriesName + \": \" + x[0].data.toFixed(3) \
  91. }").js_code
  92. },
  93. "toolbox": {
  94. "feature": {
  95. "restore": {
  96. "show": "true"
  97. },
  98. }
  99. },
  100. }
  101. events = {
  102. "dataZoom":
  103. "function(params) { return ['dataZoom', params.start, params.end] }",
  104. "restore":
  105. "function() { return ['restore'] }",
  106. "legendselectchanged":
  107. "function(params){ return ['legendselectchanged', params.name] }"
  108. }
  109. # show echart with dataZoom and update intervals based on output
  110. e = st_echarts(options=options,
  111. events=events,
  112. height="500px",
  113. key="echart_S")
  114. # e - event from echarts
  115. if e:
  116. # DataZoom event is not fired on new file upload (and in some other cases)
  117. # There is no 'default event' to fix it, so use st.experimental_rerun() with session_state
  118. if e[0] == "restore":
  119. if 0 != st.session_state.start or 100 != st.session_state.end:
  120. st.session_state.start = 0
  121. st.session_state.end = 100
  122. st.experimental_rerun()
  123. elif e[0] == "dataZoom":
  124. if e[1] != st.session_state.start or e[2] != st.session_state.end:
  125. st.session_state.start = e[1]
  126. st.session_state.end = e[2]
  127. st.experimental_rerun()
  128. elif e[0] == "legendselectchanged":
  129. if e[1] != st.session_state.legendselection:
  130. # Save selected type of series to state
  131. st.session_state.legendselection = e[1]
  132. # make chart state the same as actual state
  133. st.experimental_rerun()
  134. n = len(f)
  135. interval_start, interval_end = int(n * st.session_state.start * 0.01), int(
  136. n * st.session_state.end * 0.01)
  137. return interval_start, interval_end