It seems strange to use a function compute_iterationwise_error within which you get the error and the properties and storing them in a dict every iteration since this is extremely similar to using a Metric. Is the only reason you’re doing this this way because Metric doesn’t allow you to return dicts? The compute() needs to give a scalar?

Yes, true. But as I didn’t understand what you wanted to plot, I thought about batchwise logging…

Additionally, at the end of accumulating all these errors and properties, I want to compute the correlation between them. This is a final scalar based on all the collected data - this seems like Metric could be especially useful.

Maybe, you can use EpochMetric to accumulate errors and properties and setup compute_fn to compute the correlation. See docs 1.
Then computed value you can separately log with visdom…

Finally, if you plot the values in real time, so one property and one error per iteration, then thats great but what if i wanted to then udpate the title of the plot at the very end to include the correlation between the properties and the errors? I dont think visdom has a function for just updating the title of a plot on its own without adding an additional data point…

You can do it like that:
w = vis.line(X=np.array([1, 2, 3]), Y=np.array([1, 2, 3]), opts=dict(xlabel="x", ylabel="y", title="title-to-change"))
vis.update_window_opts(w, opts={"title": "new_title"})