Replace Highcharts plotting library with open source alternative

Issue #477 resolved
David Platten created an issue

I am working on implementing Altair, https://altair-viz.github.io/index.html

It is possible to implement charts where we calculate the mean or median at the server, then send the results to the browser:

# Create a Pandas DataFrame from the database events and annotations
df = pd.DataFrame.from_records(database_events.values(db_display_name_relationship, "db_series_names_to_use").annotate(**summary_annotations).order_by("db_series_names_to_use"))
df.rename(columns={db_display_name_relationship:"x_ray_system_name"}, inplace=True)
df.rename(columns={"db_series_names_to_use":"data_point_name"}, inplace=True)

# Change Decimal values to float so that to_json() works (Decimal values can't be JSON serialised)
df["mean"] = df["mean"].astype(float)

# Create a chart
chart = alt.Chart(df).mark_bar().encode(
    column=alt.Column("data_point_name"),
    x=alt.X("x_ray_system_name"),
    y=alt.Y("mean"),
    color="x_ray_system_name"
).interactive()

It is also easy to implement charts where we supply Altair with all of the data, and get the browser’s JavaScript to calculate the mean or median:

# Create a Pandas DataFrame from the database events
df = pd.DataFrame.from_records(database_events.values(db_display_name_relationship, "db_series_names_to_use", db_value_name))
df.rename(columns={db_display_name_relationship:"x_ray_system_name"}, inplace=True)
df.rename(columns={"db_series_names_to_use":"data_point_name"}, inplace=True)

# Change Decimal values to float so that to_json() works (Decimal values can't be JSON serialised)
df["mean"] = df[db_value_name].astype(float)

# Disable the max rows allowed in an Altair chart
alt.data_transformers.disable_max_rows()

# Create a chart
chart = alt.Chart(df).mark_bar().encode(
    column=alt.Column("data_point_name"),
    x=alt.X("x_ray_system_name"),
    y=alt.Y(db_value_name, "mean"),
    color="x_ray_system_name"
).interactive()

Sending all of the data to the browser could result in problems (maybe memory issues, or slow behaviour?). However, I wonder if keeping all the data may have advantages that I am not aware of at the moment (easy histograms in the browser, perhaps?).

29/8/2020 update: I’m now using all of the data in the data frame so that I can easily use Altair for average-over-time charts. I’ll need to test whether this is OK for large amounts of data from a server and client perspective. I’ll need to try it on a “standard” computer’s browser (my laptop has 32 GB RAM, and my desktop 64 GB).

Might be useful: https://medium.com/plotly/introducing-plotly-express-808df010143d

To do:

  • FAILED: Sort out the width of the new Altair charts

    • Replaced Altair with Plotly - size now more-or-less fixed
  • DONE: Plumb in over-time chart time period

  • DONE: Add choice of box plot or bar chart for “average” charts (if “median” selected then a boxplot is produced)
  • DONE: Add static Plotly JavaScript files rather than current links to latest on-line versions
  • DONE: Rationalise chart production code to avoid duplication of database queries (“study” and “request” level queries can share the same routines, with appropriate fields collected in the Pandas DataFrame)
  • DONE: Separate the new chart code into one function per chart. Pass each of these the Pandas DataFrame
  • DONE: Add charts of CTDIvol and DLP vs patient weight
  • DONE: Add chart of requested procedure DLP over time
  • DONE: Add charts of acquisition protocol CTDI and DLP over time
  • DONE: Workload chart: link an hourly chart to selected data in the daily chart? [actually sub-divided each day into hours in the same chart]
  • DONE: Make it possible to sort average chart x-axes by frequency, name or value. Boxplots and frequency chart data is also sortable.
  • DONE: Update mammo, radiographic and fluoro charts with this new code
  • DONE: Add DX acquisition/study/request DAP vs patient mass
  • DONE: Calculate histogram data using Numpy in Python and creating a Plotly barchart rather than embedding all the data in a Plotly Histogram chart (https://numpy.org/doc/stable/reference/generated/numpy.histogram.html). Should improve browser responsiveness if large number of histograms plotted.
  • DONE: Unlink the y-axes of the over-time sub-plots
  • DONE: added mammography charts of average AGD and average AGD vs. compressed thickness
  • DONE: Add MG chart of average acquisition AGD over time
  • DONE: Add RF charts of study description and requested procedure name DAP over time
  • DONE: Add RF chart of study description and requested procedure name DAP and frequency per physician
  • DONE: add option to fix histogram bins across subplots, or have bins calculated per subplot
  • FIXED: Switching charts “on” from home page before doing anything causes “Not found” error when trying to redirect to http://127.0.0.1:8000/&plotCharts=on
  • ON-HOLD: Add RF chart of # events per study description and requested procedure name - future
  • ON-HOLD: Add RF filter for physician - future
  • PARTIAL: Add button to download plotted data as csv; DONE for average bar charts and frequency charts

Comments (324)

  1. David Platten reporter
  2. David Platten reporter
    import plotly.offline as opy
    import cufflinks as cf
    import pandas as pd
    import numpy as np
    
    # Create a Pandas dataframe, populated with some data
    df = cf.datagen.lines()
    
    # Create a stacked bar chart figure from the dataframe
    fig = df.iplot(kind='bar', barmode='stack', asFigure=True)
    
    # Show the plot in a web page that's automatically opened
    opy.plot(fig)
    
    # Send the plot to a variable that contains all the required html in a div.
    # This could be used in a Django view as the thing to return to an html template
    div = opy.plot(fig, auto_open=False, output_type="div")
    
  3. David Platten reporter

    Replace

    fig = df.iplot(kind='bar', barmode='stack', asFigure=True)
    

    with

    fig = df.iplot(kind='box', asFigure=True)
    

    for a boxplot, or

    fig = df.iplot(kind='line', asFigure=True)
    

    for a line plot.

  4. Ed McDonagh

    I had to install ipython in addition to the ipython-something that was installed automatically before the examples you posted previously would work on my statement.

  5. Ed McDonagh

    Just had a look on my laptop rather than just on my phone - those box plots are going to make a lot of people very happy - some because they can get a feel for the distribution, others to get their misunderstood 75th centiles!

  6. David Platten reporter
  7. David Platten reporter

    Fixed broken grouped boxplot when requested procedure name is None. Also added a routine to return a list of colours that can be used for plotting (these are a bit muddy at the moment). References issue #477

    → <<cset 4a95399bb3c6>>

  8. David Platten reporter

    @LuukO , back in September 2017 you e-mailed @edmcdonagh and myself with some great suggestions about HL7 messaging and charts. In your message you included an example boxplot that you'd created using mpld3. I've always liked the idea of boxplots, and have just started to try some Plotly charts out in OpenREM - see http://testing.openrem.org/openrem/ct/?requested_procedure=ct.

    The boxplot at the top is created using cufflinks (https://plot.ly/ipython-notebooks/cufflinks/). Cufflinks is indended to be an easy way to create plotly charts from pandas dataframes.

    The second boxplot is created using a longer method, but one that allows more flexibility. This one has a box per CT scanner. It's based on this code: https://plot.ly/python/box-plots/#grouped-box-plots.

    Before I get carried away, I'd really like your thoughts on the charting, and the associated filtering of the data to produce the charts.

    Kind regards,

    David

  9. David Platten reporter

    Added histograms into the mix. Only now plotting what is asked for (the plotly charts respect the 'series per system' and 'histogram' settings). Pie chart of request frequency only shown if it's selected by the user. There's a problem with using Plotly charts as I'm doing at the moment: python passes the browser a big chunk of html and javascript for each chart. Plotting lots of charts eats up lots of (server) RAM. On my test system I get an out of memory error if I switch on histograms without filtering the data first. It may be that we should be calculating the data for charts in python, and then just passing the required information to a JavaScript Plotly library. Not sure if this will help. References issue #477

    → <<cset 50c7e1f6bb21>>

  10. Luuk

    @dplatten, I actually thinking you can't define beforehand all graphs that users want to see. So I was thinking about user definable charts and have actually something running. The user can select a graph type: scatter plot, histogram, box/whisperplot and next to that the parameter on the x and y axis and a "grouping/series" parameter:

    parameterselect.png

    The result is a graph and below the graph some descriptive statistics (scatterplot: DLP versus weight, group on display name):

    dlpversusgewicht.png

    or (box and whisper: DLP versus display name)

    dlpperStationName.png

    It is partly implemented, only for CT and the number of CT parameters are limited so far. It uses the filter set at the modality filter-page. But you actually might want to do some more advanced filtering and maybe also to event-level to be able to select specific CT-aqcuisitions and look at the CTDIvol. I'm also using numpy and pandas for this, but Bokeh for the graphics part (mpld3 seems to (almost) stopped development and doesn't implement all functionality of the underlying library, matplotlib). The problem is time at the moment. I hope to be able to work on this (filtering and user definable graphs) in some months again as I see need for it at least in our institution (people don't want to export to excel first to make graphs they like).

  11. Ed McDonagh

    Wow.

    You have both done some very exciting work on this.

    @LuukO, are you able to push your efforts into a branch in this repo so we can see what you have been working on?

  12. Luuk

    I've to look at pushing this to a branch (but probably can). It was a sort of see-what-you-can-do-pilot and it worked out quite well, but it didn't get any further than that (it actually is used at the moment: I get complaints....;-)). It shouldn't be to hard to extend to other modalities. I also like the possibility of these charts that you can click on a marker and that this will bring you to the specific study (details page in a different browsertab).

    I'll see if I have some time on Friday to have a look at pushing this.

  13. David Platten reporter

    @LuukO , your work-in-progress looks great. I have just been playing about with Plotly.

    I agree that it would be good to allow the user to define their own chart types. I think we should have some pre-defined charts, and the ability for the user to make others.

    What complaints to you get from your users?

  14. Luuk

    I just pushed branch RelatedTo477UserDefinableCharts (commit 9bc7dac). You need bokeh 0.12.9 for this to work.

    The complaints are that users want to have it available for other modalities and also want to have more possibilities. We have a saying in Dutch: "Give them a finger and they want the whole hand". I don't know if there is an English equivalent, but it means something like if you help a little, they want more help (all the time).

  15. Ed McDonagh

    Hi @LuukO. I have just pushed your branch to http://testing.openrem.org and it looks great. One issue is that it doesn't handle non-ascii strings very well, so it will fail if you don't filter to remove them first. If you filter by display name 'CT scanner' then all is well.

    I've left debug mode active for the moment.

  16. Luuk

    @edmcdonagh, thanks for publishing this. I really want to know what you all would expect this to do. This was just a proof of concept. Probably I can work on it in a few months and it would be good to think about functionality and the chart library we are going to use (also for the charts @dplatten has) in the meanwhile. I would think we will use one library in the end.

  17. David Platten reporter

    I think we should put together a statement of requirement for the charting. I also think that we should carry out an options appraisal to examine the different charting libraries. I'll make a start on these, possibly posting them here. It will need to be possible for others to comment or edit what I draft.

  18. Ed McDonagh

    I'll have a think about how we might do that... We could just have a .rst or a markdown file in the stuff folder that can be commented on and edited in the browser, or people can fork the repo and submit pull requests against it (on a branch) maybe?

    Or there is a wiki function to bitbucket that I haven't activated that maybe could be used?

    Did you have any ideas?

  19. David Platten reporter

    I think that the wiki function here on bitbucket might be good - less clunky than editing an .rst file. This would also be easily visible to other OpenREM users. I think it would be good to have input on the future of the charts from the wider OpenREM community.

  20. Ed McDonagh

    Hi @David Platten - where are you with plans for replacing HighCharts? Does it fit in with all the other major overhaul work that is about to start?

  21. David Platten reporter

    Simple Altair-based chart working for mean or median DLP per requested procedure name. No histograms at the moment, and the chart formatting isn't great. However, the chart creation and display works. References issue #830 and issue #477

    → <<cset 4c5102ae9fb6>>

  22. David Platten reporter

    Added some test code that makes the browser JavaScript calculate the mean or median values (not implemented for the combined plot of mean and median). This may cause memory or performance issues I think, due to the potentially very large object size passed to the browser. References issue #830 and issue #477

    → <<cset 5cca47bd06c9>>

  23. David Platten reporter

    Removed HighCharts-related JavaScript. Added tooltip, legend title, y-axis title. I've tried to make the chart fit the DIV, but cannot work out how to do that at the moment. References issue #830 and issue #477

    → <<cset c8f2992c8e03>>

  24. David Platten reporter

    Added stacked bar chart in place of pie chart for frequency of requested procedure names. Produces a bar per x-ray system (an improvement on the pie chart). References issue #830 and issue #477

    → <<cset b362805a40c6>>

  25. David Platten reporter

    Switched average plots so that the categories are stacked vertically (one column, lots of rows). This avoids an issue where the width gets too large. References issue #830 and issue #477

    → <<cset f1cf683996ad>>

  26. David Platten reporter

    @Ed McDonagh I don’t know what you mean by “dynamic category selection function”…

  27. David Platten reporter

    Re-write of some chart code. Using raw query data in a single function to calculate average chart, frequency chart and also average over time chart. Incomplete. References issue #477

    → <<cset 113cac739a62>>

  28. David Platten reporter

    Updated average over time and number of events charts with new Altair code. Need to plumb in the user-defined time period for the over time chart. References issue #477

    → <<cset fa593ee9527c>>

  29. Ed McDonagh

    Which charts in particular need checking @David Platten ? I could try with my production database copy on my often limping Ubuntu VM! Probably not till this evening though.

  30. Ed McDonagh

    On my VirtualBox VM @David Platten , a CT filter of four CT units for TAP scans since 2010, ~96,000 studies, the page load was 32 seconds (not unusual on this system to be so slow), and the median study DLP over time in days with a series per system took a further 15 seconds, which is a lot quicker than I’m used to with HighCharts. Smaller filter ranges give the chart in just a few seconds, so it seems to work well.

    However, it appears that the per day setting is ignored, and just presents per month no-matter what is selected - has this setting not been plumbed in yet?

  31. David Platten reporter

    @Ed McDonagh thanks for checking. I haven’t plumbed in the date choice for the over time chart yet. Glad the charts works ok on your VM system. I’m going to add boxplots too, perhaps as a user choice (bar chart or boxplot).

  32. Ed McDonagh

    @David Platten - it would be good to be able to plot CTDIvol and DLP vs patient weight in the browser if it works sufficiently fast. Thanks.

  33. David Platten reporter

    Made legend interactive. Clicking on a legend entry reduces the opacity of other entries to 0.1. Multiple entries can be selected using shift+click. Clicking somewhere off a legend entry returns all entries to opacity of 1.0. Also fixed typo in frequency chart key name. References issue #477

    → <<cset faf75a8bb297>>

  34. David Platten reporter

    CT over-time chart now respects user choice of time period. Removed weekly option as this is not available as an Altair TimeUnit transform. Rotated text on x-axis of over-time chart by 90 degrees. References issue #477

    → <<cset b259aeee4f9e>>

  35. David Platten reporter

    Increased limit on legend entries to 250 in the over-time chart. Changed legent title so it reflects the provided category name. References issue #477

    → <<cset c4e8ed82ccb2>>

  36. David Platten reporter

    Frequency chart legend entries now sorted in order of descending frequency. Also increased maximum legend entries to 250 and changed legend title to reflect the chart content. References issue #477

    → <<cset 3675ac6cefaf>>

  37. David Platten reporter

    Separate data for each system in histograms now; click on legend to show / hide series. Average chart of mean and median now plotted correctly (not stacked). References issue #477

    → <<cset c242425290f1>>

  38. David Platten reporter

    Temporary replacement of bar chart code with boxplot code as proof-of-concept. Boxplots do not support selections at the moment, so cannot click on the legend to change opacity of any of the series. References issue #477

    → <<cset 485f8701c8e5>>

  39. David Platten reporter

    Case-insensitive setting: removed unnecessary annotation of the QuerySet; doing this in the Pandas DataFrame instead. I've also just realised that we don't need the database median function anymore, as the averages are calculated by Altair: medians will now work with any database (although I've not verified that this works). References issue #477 and #241

    → <<cset af235ae18b13>>

  40. David Platten reporter

    Started to look at setting width of charts to fit container. This seems to break the ability to select series via the legent - look at inspect window in Chrome. References issue #477

    → <<cset 41b5c1f17493>>

  41. David Platten reporter

    Refactored Altair chart code into separate functions per chart type. Added all CT histograms. All CT charts now using Altair. Workload chart doesn't have per-hour data at the moment. References issue #477 and #830

    → <<cset 2e9307e994b9>>

  42. David Platten reporter

    @Ed McDonagh would you take a look at the example Plotly charts that I have added? You need to select the CT DLP per requested procedure chart for them to show up. I think that Plotly may be better than Altair. The charts resize properly for a start, and I think I’ll be able to make a button to save the plotting data as csv. Any thoughts welcome.

  43. David Platten reporter

    Fixed resizing JavaScript so that it works when the mean and median (boxplot) charts are present. Removed the fullstops from the chart titles. References issue #477

    → <<cset b805c5664381>>

  44. David Platten reporter

    Updated resize code with something that should work with Internet Explorer (untested). Trying to get resize to work. Nearly there. Plotly menu is mid-way down the plot after exiting full-screen. Not sure why. References issue #477

    → <<cset eae6a811ea50>>

  45. David Platten reporter

    Implemented Plotly charts for the remaining CT average charts. Need to produce a Plotly frequency chart, over-time chart and workload chart. References issue #477

    → <<cset d96e672fa43a>>

  46. David Platten reporter

    Added Plotly time series CT chart. Added 'Weeks' option back in, and also 'Quarters'. If the user has selected 'Both' as the average choice then two line charts are produced: one of mean values, and one of medians. At the moment the averaging takes place up to the end of the time period. For example, if the user has selected 'Months' then there will be a data point on the last day of each month that is the average of the studies that took place up to that date. References issue #477

    → <<cset 4927ded5099a>>

  47. David Platten reporter

    Added Plotly chart of workload per weekday. Haven't added the ability to look at studies within each hour of the day yet. References issue #477

    → <<cset b24c31b75ba6>>

  48. David Platten reporter

    Added scatter plots of DLP and CTDI vs patient mass for each acquisition protocol. Not sure if it works because my test system has no patient mass data. Will check on the online testing.openrem.org server. References issue #477

    → <<cset 14e2435007e7>>

  49. David Platten reporter

    Replaced the repeat chart sections in ctfiltered.html with a loop, reducing length of this file by around 500 lines (!). References issue #477

    → <<cset 48aac8ada665>>

  50. David Platten reporter

    Made over-time period more generic so I can use it for some new over-time plots that I am planning. Over-time charts can now respect the grouping choice. References issue #477

    → <<cset b59543d8ae65>>

  51. David Platten reporter

    Added over-time period charts for CT acquisition CTDI and DLP and also requested procedure DLP. Added warning message if a particular chart cannot be calculated (too many categories it seems). References issue #477

    → <<cset 08afefa0c4ba>>

  52. David Platten reporter

    Configured charts to hide the link to Plotly. Configured charts to save as 1920x1080 png files with a filename specific to each chart. References issue #477

    → <<cset 15ebc422daa3>>

  53. David Platten reporter

    Box plot and average bar chart data can now be sorted with name, value or frequency in ascending or descending order. Frequency plots can be sorted in frequency or name order. References issue #477

    → <<cset cda550fd97bb>>

  54. David Platten reporter

    Increased max length of DX and RF sorting choice field to accommodate the word 'frequency'. I'm pretty sure this is why the pipeline failed for the previous commit. References issue #477

    → <<cset 5da9310c8e9e>>

  55. David Platten reporter

    Calculating aggregates for mean bar charts and frequency charts in Python (already calculating these for over-time and workload charts). Should make it easier to implement tests. Made remaining charts respect sorting order. References issue #477

    → <<cset 37a051d2ecd7>>

  56. David Platten reporter

    Updated existing fluoroscopy charts to use Plotly. Need to carefully check that dataframes contain all the data I think: had an issue with just a frequency plot where the 10000+ studies resulted in a dataframe with 87 rows. These were all the unique requested names. I have added the study_instance_uid field to each data frame to ensure that every study is represented. However, I'm not sure if there are implications for individual acquisitions. References issue #477

    → <<cset 79ccc21dc00a>>

  57. David Platten reporter

    Attempting to sort out issue where query set rows with matching values only appear once in data frame. This commit doesn't fix it. References issue #477

    → <<cset 536d0ae62aad>>

  58. David Platten reporter

    Added study_instance_uid to dataframe to ensure that data is obtained for every required study. If this is not used then the .distinct() that is applied to the source queryset means that only unique field combinations are returned. Also added multiplier for fluoro dataframe to make DAP values cGy.cm2. References issue #477

    → <<cset 53e34513a70e>>

  59. David Platten reporter

    Implemented Plotly charts for radiographic page. Deleted non-Plotly code from the chart calculations. Added logic to extend height of facet-based charts when multiple rows are present (250 px per row; minimum height of 750 px). References issue #477

    → <<cset 667a2f284b01>>

  60. Ed McDonagh

    Hi @David Platten

    For the DX charts, can we have acquisition/study DAP vs pt weight please?

    Also, on testing it is telling me that DAP isn’t a valid choice for chart sorting.

  61. David Platten reporter

    Looking at a simple bar chart of median as well as mean, with boxplot as an additional option. Implemented for rf study chart. I like the simple median chart as the boxplot can be a bit busy, especially if there are a large number of outliers that compress the median values. References issue #477

    → <<cset 744b2110a428>>

  62. David Platten reporter

    @Ed McDonagh I have changed the names of the sorting choices, so the first time you go to the page it will give you the “DAP isn’t a valid choice” message. Just pick one of the new choices and click submit and you should never see that message again.

    I’ve changed the options to be more generic: “Name, Value or Frequency”

    I think there should be more mammo and fluoro charts. What might you find useful?

  63. Ed McDonagh

    @David Platten I’ve brought the current branch into my system with a copy of the production database, but I can’t get any charts to render!

    For mammo and fluoro, the spinning never stops. For CT, I get the message

    Could not resolve chart. Try filtering the data to reduce the number of categories or systems.
    

    I haven’t experimented extensively with different combinations of charts and options.

    Somehow DX did work (Chart of median DAP for each study description)

  64. David Platten reporter

    @Ed McDonagh that message comes up when Plotly has a ValueError when constructing a plot, usually because there are so many systems or series that the facet-based plots fail.

    Can you try single plots, using the “system” grouping option and see how you get on?

  65. David Platten reporter

    Adding detail to error message if charts fail and debug is on. Adjusted facet_row_spacing so I think the error is unlikely to appear now; may result in a large number of sub-plots and put a strain on the browser. References issue #477

    → <<cset 0e8f6f921280>>

  66. David Platten reporter

    Added radiographic charts of acquisition, study and requst DAP vs patient mass. Ed - please feed back on these as I have no radiographic patient mass data in my test system. References issue #477

    → <<cset 1e31e3345949>>

  67. Ed McDonagh

    Can I check @David Platten - has this branch changed the filtering (using charts or not) for acquisition level filters?

    I ask because if I have DX with a study filter and an acquisition filter, it takes a very long time to return (if it does). If I remove the acquisition level filter, it comes back in a reasonable time.

    I haven’t done the proper investigations (checking the develop branch for the same behaviour etc) - I just wanted to check first off if you think it has changed.

  68. David Platten reporter

    First attempt at histogram chart calculated in Python using Numpy. Only active for histograms of the CT chart of requested procedure DLP. References issue #477

    → <<cset f496a2816e42>>

  69. David Platten reporter

    Numpy-based histograms now working. Only implemented for CT requested procedure chart at the moment. All data calculated in Python; just bar values passed to browser. References issue #477

    → <<cset a51448610465>>

  70. David Platten reporter

    Converting all named columns and the system name column in the data frame to be of type 'category'. This saves a significant amount of (server) system memory. References issue #477

    → <<cset dddce69b44be>>

  71. David Platten reporter

    Switched all histograms to use the new Numpy-based histograms. All histogram data now calculated in Python; just bar values passed to browser. References issue #477

    → <<cset 1383a15276ce>>

  72. David Platten reporter

    Added uid field to dataframe creation. Need a study (request) level one for those charts, and an acquisition-level one for the acquisition charts. I expect a similar approach will work with the other modalities, provided that the xx_acq_filter is being used (which it is not at least for DX). References issue #477

    → <<cset 1f20e7c43ff8>>

  73. David Platten reporter

    Switched to using dx_acq_filter for radiographic charts. Now using separate acquisition- and study/request-level data frames for radiographic charts. I think the radiographic charts. References issue #477

    → <<cset 6442f657fa32>>

  74. David Platten reporter

    Added some spacing between rows of histogram facets. Adding value labels to x and y axes for scatter and line plots. References issue #477

    → <<cset fdabb6854ae1>>

  75. David Platten reporter

    Changed chart average choice to be mean, median, boxplot. Implemented for all modalities. Ensuring the frequency charts are sorted in the same way as any existing average charts. References issue #477

    → <<cset 632fb4b76e06>>

  76. David Platten reporter

    Added mammography chart of average AGD in specificed compressed breast thickness bands. Need to add user-option to configure the bands. Need to amend upper and lower bin labels to make it clear that lowest bin includes any values below min, and upper bin includes any values above the max value. Will probably add an extra bin at the top and bottom if the user choice does not incorporate all the data. Refs issue #477

    → <<cset 6db517cf496d>>

  77. David Platten reporter

    Forgot to add logic to include fields in data frame for new chart. Would be good to indicate number of values included in each bar in tooltip. Refs issue #477

    → <<cset df7dc05dc738>>

  78. David Platten reporter

    Added bin at either end to capture data below and above the user-specified range. Removing nan data before calculating the binned stats chart or scatter chart. Refs issue #477

    → <<cset faa3874ae50d>>

  79. David Platten reporter

    Added check that there is still data for a particular category after nan has been removed. Using .values for histogram and binned_statistic functions. Refs issue #477

    → <<cset 111b666d038f>>

  80. David Platten reporter

    @Ed McDonagh the compressed breast thickness bands are hard-written into the chart code at the moment. I would like to enable each user to choose their own bands, via a database table linked to their UserProfile. I’m not sure how to go about doing that, and wondered if you might be able to help?

  81. Ed McDonagh

    Haven’t isolated it, but in trying to look at the average AGD chart, I go this:

    /path/to/my/venv/lib/python3.8/site-packages/numpy/lib/histograms.py:433: RuntimeWarning:
    
    invalid value encountered in greater
    

    Chart of AGD vs compressed breast thickness for each acquisition protocol and Chart of mean AGD for each acquisition protocol were both selected.

  82. David Platten reporter

    Added mammography histograms. Altered wording of chart titles. Mammo study workload data incorrect at the moment as it is using acquisition numbers rather than study numbers. Refs issue #477

    → <<cset 06ac493e2e30>>

  83. David Platten reporter

    Modified mammo chart views so there is an acquisition-level data frame and a study/request level one. Study workload chart now correct. Refs issue #477

    → <<cset cfe1c70ab7f9>>

  84. David Platten reporter

    Adding utility code to create swatches of each chart colour map choice. I'm going to incorporate these images into the form where the user chooses which colour map they want to use. Refs issue #477

    → <<cset 7b19a78f6953>>

  85. David Platten reporter

    Added label around each list item so that the user can click on the swatch to select it, rather than having to specifically click on the radio button. Added a 1px border around each colour swatch. Refs issue #477

    → <<cset 9ac1596cdab0>>

  86. David Platten reporter

    Plumbing dict option into the view. Correcting an error with the CT num events charts that was preventing some from being displayed or calculated. Refs issue #477 and #686

    → <<cset 8d1ca21edaa6>>

  87. David Platten reporter

    Added tests of radiographic acquisition kVp. Improved box plot checking so it sorts data pairs first by value then by name so that the order is consistend when there are several pairs with the same name but different values. Refs issue #477

    → <<cset 28df086695fd>>

  88. David Platten reporter

    Initial mammography chart tests now working locally: I had missed out when setting the required charts. Hopefully they will run on BitBucket too. Refs issue #477

    → <<cset 817d87db0275>>

  89. David Platten reporter

    Corrected bug in DX chart code where study and request level dataframe was calculated whatever the user had set. Adding specific format to study date as this speeds up the conversion when a large number of entries is being handled. Refs issue #477

    → <<cset fc8965ab6592>>

  90. David Platten reporter

    Removing display of weekday index in workload charts. Reducing memory footprint of weekday chart dataframe. Upgrading pandas to the latest version. Refs issue #477

    → <<cset 4a71d3f1e339>>

  91. David Platten reporter

    Addressing failed tests (hooray for tests) Adding display of weekday back into workload charts; changed weekday field back to object so the full name is displayed (uses more memory). Refs issue #477

    → <<cset 997067f34c98>>

  92. David Platten reporter

    Added display of frequency in the hover data for each data point in over-time charts. Added check for empty data frame. Added appropraite label for series name in the hover, such as 'Acquisition protocol' or 'Study description'. Refs issue #477

    → <<cset f2fdfa62a27a>>

  93. David Platten reporter

    Replaced 'Swich charts off' option in the main menu with one that switches them off if they're already on, or on if they're currently off. Refs issue #477

    → <<cset 895f21b12b86>>

  94. David Platten reporter

    Added option to fix histogram bins across all subplots for a particlar chart, or have bins calculated for each individual subplot. Refs issue #477

    → <<cset 03752292c6bb>>

  95. David Platten reporter

    Addressing Codacy issues in chart_functions.py. Moved all imports to top of the file. Refactored error message into a method. Also now showing color map names next to the swatch on the chart options page. Refs issue #477

    → <<cset b19b4a14fd65>>

  96. David Platten reporter

    Labelling mark_safe entries in forms.py as # nosec so it is ignored by Codacy. I believe that running Black will move this comment to the end of the line, stopping it from working... Refs issue #477

    → <<cset cfc155ac00ba>>

  97. David Platten reporter

    Addressing Codacy issues. Removed duplicate variables in models.py and forms.py. Removed Median class, median_available and plotAverageChoice fields from models.py. Refs issue #477

    → <<cset 71cc4f31ae44>>

  98. David Platten reporter

    Addressing Codacy issues. Reordered some imports. Renamed stats parameter. Simplifying if statement logic by using any() when there are lots of choices. Refs issue #477

    → <<cset 226466d0a780>>

  99. David Platten reporter

    Removed check for numpy in views.py and views_admin.py that set plotting variable: this is never used. Also rearranged order of imports in views.py. Refs issue #477

    → <<cset 36b5ff619881>>

  100. David Platten reporter

    Moving imports a bit. Also sending create_dataframe a dictionary of fields to reduce the number of local variables. Will do something similar with the plot creation routines if Codacy is happy. Refs issue #477

    → <<cset b7ff530b1923>>

  101. David Platten reporter

    Reduced local variables in plotly_boxplot method. Changed order of required_charts in each view so that it matches the order that the charts appear in the chart form. Refs issue #477

    → <<cset 10e7d2d97552>>

  102. David Platten reporter

    Disabling pylint check of number of local variables for histogram. Changed import of pickle so there is no renaming. Still works. Added pylint disable-line-too-long in views_charts_dx.py. Refs issue #477

    → <<cset a3b6ce5e1a06>>

  103. Ed McDonagh

    Hi @David Platten . Is it possible to isolate a series name for the charts?

    So if I have four CT scanners, and I want to compare the Thorax^TAP protocols by weight, I can either group by system and disable all the extraneous series names in the charts, which gives me a system per chart.

    Or I can group by series name and then I get all the scanners (with matched protocol series names!) on one chart, but I have 20 other charts of all the extraneous series names.

    Is there anything I can use to get me a cleaner display?

  104. Ed McDonagh

    Doh! Yes - adding the acquisition name of TAP cuts it down to a much more manageable five charts!

  105. David Platten reporter

    Fixing issue where exclusion of lots of missing data causes height of each chart subplot to be very large. Calculating the chart height after the exclusion fixes this. Refs issue #477

    → <<cset d5927e1f6a63>>

  106. Log in to comment