Skip to content

Commit

Permalink
fix(visualize): Add option for 24-hour clock in HourlyPlot
Browse files Browse the repository at this point in the history
  • Loading branch information
chriswmackey authored and Chris Mackey committed Jun 13, 2023
1 parent 92b292a commit 8a922af
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 4 deletions.
11 changes: 9 additions & 2 deletions ladybug_grasshopper/json/LB_Hourly_Plot.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "1.6.0",
"version": "1.6.1",
"nickname": "HourlyPlot",
"outputs": [
[
Expand Down Expand Up @@ -90,6 +90,13 @@
"type": "bool",
"default": null
},
{
"access": "item",
"name": "clock_24_",
"description": "Boolean to note whether the hour labels on the Y-Axis of the chart\nshould be in 24-hour clock format (eg. 18:00) or they should be\nin 12-hour clock format (eg. 6PM).",
"type": "bool",
"default": null
},
{
"access": "list",
"name": "legend_par_",
Expand All @@ -113,7 +120,7 @@
}
],
"subcategory": "2 :: Visualize Data",
"code": "\ntry:\n from ladybug.datacollection import HourlyContinuousCollection\n from ladybug.hourlyplot import HourlyPlot\nexcept ImportError as e:\n raise ImportError('\\nFailed to import ladybug:\\n\\t{}'.format(e))\n\ntry:\n from ladybug_geometry.geometry3d.pointvector import Point3D\n from ladybug_geometry.geometry3d.plane import Plane\nexcept ImportError as e:\n raise ImportError('\\nFailed to import ladybug_geometry:\\n\\t{}'.format(e))\n\ntry:\n from ladybug_{{cad}}.config import conversion_to_meters\n from ladybug_{{cad}}.togeometry import to_point3d\n from ladybug_{{cad}}.fromgeometry import from_mesh3d, from_mesh2d, \\\n from_polyline2d, from_linesegment2d\n from ladybug_{{cad}}.text import text_objects\n from ladybug_{{cad}}.fromobjects import legend_objects\n from ladybug_{{cad}}.{{plugin}} import all_required_inputs, list_to_data_tree, \\\n objectify_output\nexcept ImportError as e:\n raise ImportError('\\nFailed to import ladybug_{{cad}}:\\n\\t{}'.format(e))\n\n\nif all_required_inputs(ghenv.Component):\n # apply any analysis periods and conditional statements to the input collections\n if period_ is not None:\n _data = [coll.filter_by_analysis_period(period_) for coll in _data]\n if statement_ is not None:\n _data = HourlyContinuousCollection.filter_collections_by_statement(\n _data, statement_)\n\n # set default values for the chart dimensions\n _base_pt_ = to_point3d(_base_pt_) if _base_pt_ is not None else Point3D()\n _x_dim_ = _x_dim_ if _x_dim_ is not None else 1.0 / conversion_to_meters()\n _y_dim_ = _y_dim_ if _y_dim_ is not None else 4.0 / conversion_to_meters()\n _z_dim_ = _z_dim_ if _z_dim_ is not None else 0\n reverse_y_ = reverse_y_ if reverse_y_ is not None else False\n\n # empty lists of objects to be filled with visuals\n mesh, title, all_legends, all_borders, all_labels, vis_set = [], [], [], [], [], []\n\n for i, data_coll in enumerate(_data):\n try: # sense when several legend parameters are connected\n lpar = legend_par_[i]\n except IndexError:\n lpar = None if len(legend_par_) == 0 else legend_par_[-1].duplicate()\n\n # create the hourly plot object and get the main pieces of geometry\n hour_plot = HourlyPlot(data_coll, lpar, _base_pt_,\n _x_dim_, _y_dim_, _z_dim_, reverse_y_)\n \n msh = from_mesh2d(hour_plot.colored_mesh2d, _base_pt_.z) if _z_dim_ == 0 else \\\n from_mesh3d(hour_plot.colored_mesh3d)\n mesh.append(msh)\n border = [from_polyline2d(hour_plot.chart_border2d, _base_pt_.z)] + \\\n [from_linesegment2d(line, _base_pt_.z) for line in hour_plot.hour_lines2d] + \\\n [from_linesegment2d(line, _base_pt_.z) for line in hour_plot.month_lines2d]\n all_borders.append(border)\n legnd = legend_objects(hour_plot.legend)\n all_legends.append(legnd)\n tit_txt = text_objects(hour_plot.title_text, hour_plot.lower_title_location,\n hour_plot.legend_parameters.text_height,\n hour_plot.legend_parameters.font)\n title.append(tit_txt)\n\n # create the text label objects\n label1 = [text_objects(txt, Plane(o=Point3D(pt.x, pt.y, _base_pt_.z)),\n hour_plot.legend_parameters.text_height,\n hour_plot.legend_parameters.font, 2, 3)\n for txt, pt in zip(hour_plot.hour_labels, hour_plot.hour_label_points2d)]\n label2 = [text_objects(txt, Plane(o=Point3D(pt.x, pt.y, _base_pt_.z)),\n hour_plot.legend_parameters.text_height,\n hour_plot.legend_parameters.font, 1, 0)\n for txt, pt in zip(hour_plot.month_labels, hour_plot.month_label_points2d)]\n all_labels.append(label1 + label2)\n\n # increment the base point so that the next chart doesn't overlap this one\n try:\n next_aper = _data[i + 1].header.analysis_period\n next_tstep = next_aper.timestep\n next_hour = next_aper.end_hour - next_aper.st_hour + 1\n except IndexError:\n next_tstep = 1\n next_hour = 24\n txt_dist = hour_plot.legend_parameters.text_height * (len(_data[i].header.metadata) + 6) * 1.5\n increment = (next_hour * next_tstep * _y_dim_) + txt_dist\n _base_pt_ = Point3D(_base_pt_.x, _base_pt_.y - increment, _base_pt_.z)\n\n # append the VisualizationSet arguments with fixed geometry\n hp_leg_par3d = hour_plot.legend_parameters.properties_3d\n hp_leg_par3d.base_plane = hp_leg_par3d.base_plane\n hp_leg_par3d.segment_height = hp_leg_par3d.segment_height\n hp_leg_par3d.segment_width = hp_leg_par3d.segment_width\n hp_leg_par3d.text_height = hp_leg_par3d.text_height\n vis_set.append((hour_plot, _base_pt_.z))\n\n # convert nexted lists into data trees\n legend = list_to_data_tree(all_legends)\n borders = list_to_data_tree(all_borders)\n labels = list_to_data_tree(all_labels)\n vis_set = objectify_output('VisualizationSet Aruments [HourlyPlot]', vis_set)\n",
"code": "\ntry:\n from ladybug.datacollection import HourlyContinuousCollection\n from ladybug.hourlyplot import HourlyPlot\nexcept ImportError as e:\n raise ImportError('\\nFailed to import ladybug:\\n\\t{}'.format(e))\n\ntry:\n from ladybug_geometry.geometry3d.pointvector import Point3D\n from ladybug_geometry.geometry3d.plane import Plane\nexcept ImportError as e:\n raise ImportError('\\nFailed to import ladybug_geometry:\\n\\t{}'.format(e))\n\ntry:\n from ladybug_{{cad}}.config import conversion_to_meters\n from ladybug_{{cad}}.togeometry import to_point3d\n from ladybug_{{cad}}.fromgeometry import from_mesh3d, from_mesh2d, \\\n from_polyline2d, from_linesegment2d\n from ladybug_{{cad}}.text import text_objects\n from ladybug_{{cad}}.fromobjects import legend_objects\n from ladybug_{{cad}}.{{plugin}} import all_required_inputs, list_to_data_tree, \\\n objectify_output\nexcept ImportError as e:\n raise ImportError('\\nFailed to import ladybug_{{cad}}:\\n\\t{}'.format(e))\n\n\nif all_required_inputs(ghenv.Component):\n # apply any analysis periods and conditional statements to the input collections\n if period_ is not None:\n _data = [coll.filter_by_analysis_period(period_) for coll in _data]\n if statement_ is not None:\n _data = HourlyContinuousCollection.filter_collections_by_statement(\n _data, statement_)\n\n # set default values for the chart dimensions\n _base_pt_ = to_point3d(_base_pt_) if _base_pt_ is not None else Point3D()\n _x_dim_ = _x_dim_ if _x_dim_ is not None else 1.0 / conversion_to_meters()\n _y_dim_ = _y_dim_ if _y_dim_ is not None else 4.0 / conversion_to_meters()\n _z_dim_ = _z_dim_ if _z_dim_ is not None else 0\n reverse_y_ = reverse_y_ if reverse_y_ is not None else False\n\n # empty lists of objects to be filled with visuals\n mesh, title, all_legends, all_borders, all_labels, vis_set = [], [], [], [], [], []\n\n for i, data_coll in enumerate(_data):\n try: # sense when several legend parameters are connected\n lpar = legend_par_[i]\n except IndexError:\n lpar = None if len(legend_par_) == 0 else legend_par_[-1].duplicate()\n\n # create the hourly plot object and get the main pieces of geometry\n hour_plot = HourlyPlot(data_coll, lpar, _base_pt_,\n _x_dim_, _y_dim_, _z_dim_, reverse_y_)\n \n msh = from_mesh2d(hour_plot.colored_mesh2d, _base_pt_.z) if _z_dim_ == 0 else \\\n from_mesh3d(hour_plot.colored_mesh3d)\n mesh.append(msh)\n border = [from_polyline2d(hour_plot.chart_border2d, _base_pt_.z)] + \\\n [from_linesegment2d(line, _base_pt_.z) for line in hour_plot.hour_lines2d] + \\\n [from_linesegment2d(line, _base_pt_.z) for line in hour_plot.month_lines2d]\n all_borders.append(border)\n legnd = legend_objects(hour_plot.legend)\n all_legends.append(legnd)\n tit_txt = text_objects(hour_plot.title_text, hour_plot.lower_title_location,\n hour_plot.legend_parameters.text_height,\n hour_plot.legend_parameters.font)\n title.append(tit_txt)\n\n # create the text label objects\n hr_text = hour_plot.hour_labels_24 if clock_24_ else hour_plot.hour_labels\n label1 = [text_objects(txt, Plane(o=Point3D(pt.x, pt.y, _base_pt_.z)),\n hour_plot.legend_parameters.text_height,\n hour_plot.legend_parameters.font, 2, 3)\n for txt, pt in zip(hr_text, hour_plot.hour_label_points2d)]\n label2 = [text_objects(txt, Plane(o=Point3D(pt.x, pt.y, _base_pt_.z)),\n hour_plot.legend_parameters.text_height,\n hour_plot.legend_parameters.font, 1, 0)\n for txt, pt in zip(hour_plot.month_labels, hour_plot.month_label_points2d)]\n all_labels.append(label1 + label2)\n\n # increment the base point so that the next chart doesn't overlap this one\n try:\n next_aper = _data[i + 1].header.analysis_period\n next_tstep = next_aper.timestep\n next_hour = next_aper.end_hour - next_aper.st_hour + 1\n except IndexError:\n next_tstep = 1\n next_hour = 24\n txt_dist = hour_plot.legend_parameters.text_height * (len(_data[i].header.metadata) + 6) * 1.5\n increment = (next_hour * next_tstep * _y_dim_) + txt_dist\n _base_pt_ = Point3D(_base_pt_.x, _base_pt_.y - increment, _base_pt_.z)\n\n # append the VisualizationSet arguments with fixed geometry\n hp_leg_par3d = hour_plot.legend_parameters.properties_3d\n hp_leg_par3d.base_plane = hp_leg_par3d.base_plane\n hp_leg_par3d.segment_height = hp_leg_par3d.segment_height\n hp_leg_par3d.segment_width = hp_leg_par3d.segment_width\n hp_leg_par3d.text_height = hp_leg_par3d.text_height\n vis_set.append((hour_plot, _base_pt_.z))\n\n # convert nexted lists into data trees\n legend = list_to_data_tree(all_legends)\n borders = list_to_data_tree(all_borders)\n labels = list_to_data_tree(all_labels)\n vis_set = objectify_output('VisualizationSet Aruments [HourlyPlot]', vis_set)\n",
"category": "Ladybug",
"name": "LB Hourly Plot",
"description": "Create a colored plot of any hourly data collection.\n-"
Expand Down
8 changes: 6 additions & 2 deletions ladybug_grasshopper/src/LB Hourly Plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
reverse_y_: Boolean to note whether the Y-axis of the chart is reversed
If True, time over the course of the day will flow from the top of
the chart to the bottom instead of the bottom to the top.
clock_24_: Boolean to note whether the hour labels on the Y-Axis of the chart
should be in 24-hour clock format (eg. 18:00) or they should be
in 12-hour clock format (eg. 6PM).
legend_par_: An optional LegendParameter object to change the display of the
HourlyPlot. This can also be a list of legend parameters to be
applied to the different connected _data.
Expand Down Expand Up @@ -61,7 +64,7 @@

ghenv.Component.Name = "LB Hourly Plot"
ghenv.Component.NickName = 'HourlyPlot'
ghenv.Component.Message = '1.6.0'
ghenv.Component.Message = '1.6.1'
ghenv.Component.Category = 'Ladybug'
ghenv.Component.SubCategory = '2 :: Visualize Data'
ghenv.Component.AdditionalHelpFromDocStrings = '1'
Expand Down Expand Up @@ -134,10 +137,11 @@
title.append(tit_txt)

# create the text label objects
hr_text = hour_plot.hour_labels_24 if clock_24_ else hour_plot.hour_labels
label1 = [text_objects(txt, Plane(o=Point3D(pt.x, pt.y, _base_pt_.z)),
hour_plot.legend_parameters.text_height,
hour_plot.legend_parameters.font, 2, 3)
for txt, pt in zip(hour_plot.hour_labels, hour_plot.hour_label_points2d)]
for txt, pt in zip(hr_text, hour_plot.hour_label_points2d)]
label2 = [text_objects(txt, Plane(o=Point3D(pt.x, pt.y, _base_pt_.z)),
hour_plot.legend_parameters.text_height,
hour_plot.legend_parameters.font, 1, 0)
Expand Down
Binary file modified ladybug_grasshopper/user_objects/LB Hourly Plot.ghuser
Binary file not shown.
Binary file modified samples/outdoor_comfort.gh
Binary file not shown.

0 comments on commit 8a922af

Please sign in to comment.