I have created a chart with following code:
ChartAmalkerd.Titles[0].Text = "xxxx";
ChartAmalkerd.Series.Add("x");
ChartAmalkerd.Series["x"].ChartType = SeriesChartType.Column;
ChartAmalkerd.Series["x"]["PointWidth"] = (0.5).ToString();
ChartAmalkerd.Series["x"].Points.AddY(10);
ChartAmalkerd.Series["x"].IsValueShownAsLabel = true;
ChartAmalkerd.Series.Add("y");
ChartAmalkerd.Series["y"].ChartType = SeriesChartType.Column;
ChartAmalkerd.Series["y"].Points.AddY(20);
ChartAmalkerd.Series["y"]["PointWidth"] = (0.5).ToString();
ChartAmalkerd.Series["y"].IsValueShownAsLabel = true;
ChartAmalkerd.Series.Add("y");
ChartAmalkerd.Series["z"].ChartType = SeriesChartType.Column;
ChartAmalkerd.Series["z"].Points.AddY(20);
ChartAmalkerd.Series["z"]["PointWidth"] = (0.5).ToString();
ChartAmalkerd.Series["z"].IsValueShownAsLabel = true;
but the columns are together and there is no any gap between columns.
How do I add a gap between columns?
I would normally come up with less hacky solutions, but as I have no time to research tonight - I at least have semi-solutions that might serve your purpose depending on your requirements, so I will give you something to start with.
What you are experiencing is the default mschart behavior if you do not set an X datapoint for this chart type.
If you never set an x for the points in a series each datapoint 'x' will be defined by the data point index position within its series + 1. You are using three series, each with one data point, so in your example all points are set to an x value of 1 automatically.
Based on this, each column above will be squeezing in to be drawn as close to their automatically generated x value as possible, which in this case, all points are x = 1.
There may be a better workaround, however, one solution to this would be to assign an x value with an offset based on the number of series/data points you plan on using.
If you know you are going to have three series you can add apply a unique offset for each series
For example
chart1.Series["x"].Points.AddXY(chart1.Series["x"].Points.Count + 1 - 0.05, yValue);
chart1.Series["y"].Points.AddXY(chart1.Series["y"].Points.Count + 1, yValue);
chart1.Series["z"].Points.AddXY(chart1.Series["z"].Points.Count + 1 + 0.05, yValue);
NOTICE: You will discover interesting 'bugs'/features if you do not add the '+ 1' to the datapoint count for series "y" above. Without it, the first data point of series 'y' will be zero. When you leave things at zero, microsoft charting will assume you have not set anything and use a default behavior.
Another hacky workaround is less pretty if you are using grid lines, but it will work.
Use your original code, but add white borders!
i.e. add this to each series (or perhaps just the center series)
chart1.Series["y"].BorderWidth = 2;
chart1.Series["y"].BorderColor = Color.White;
The workaround code examples I cite are tailored to your code sample above, which has three series, each with one data point, but can be adapted for more series and more data points per series to make it more dynamic. Let me know if you need help with such a task and I will try to get you going.
I will return and edit this answer later if I have time to research a less hacky answer this weekend. Good luck!
chart1.Series["y"].BorderWidth = 2;
chart1.Series["y"].BorderColor = Color.Transparent;
works nicely.
Related
I haven't really played around with it, as I'm not aware of a method to add a second x-axis to the top of a ggplot, and even if I were, I wouldn't really know how to 'collect' how many parameters are still in the model as lambda increases, as shown in a plot.glmnet()
In other words, do you have any idea how to make a plot like below in ggplot? Is it even possible?
plot.glmnet with x = log(lambda), y = coefficients and top x-axis = number of parameters still left in the model, given a specific value of log(lambda)
Haven't tried anything - I'm just curious :-)
Lets consider I am given a plot and I do not have its x and y vectors but I would like to extract them from the plot in Matlab. Also I am interested to know the increment of data (step size) in both horizontal and vertical axis(x and y axis).
I was thinking of using :
h=gca % Get current axis
X=get(h,'xdata');
Y=get(h,'ydata');
stepsize=X(2)-X(1);
But these command produce an error message that :
xdata and ydata are not accessible property of axis. Any suggestion how to find the x and y vectors for any given curve.
If I understand correctly, these are the two things you want to know:
You have a figure containing a plot of some arbitrary 2d line, whose x_vec, y_vec are unknown to you and you want to extract them from the figure\axes.
You want to get the xtick and ytick positions used in the figure you have.
The reason your code does not work, is because you're trying to access a property of the axes, whereas what you want to access is the property of the line (i.e. the curve in the plot).
To solve your first problem, you can resort to the following methods:
Manual: using the edit plot figure tool you can get to the XData and YData properties of the line, in the following manner:
Programmatic: you need to find the handle (i.e. pointer) to the line, and then use your code on that handle (and not on gca):
%// If there's only one entity (child) in the axes:
hLine = get(gca,'Children');
%// If there's more than one child:
hChildren = findobj(gca,'Type','line');
hLine = hChildren(1); %// Or any other logic you need to pick the correct line
%// Then comes your code:
xD = get(hLine,'XData'); yD = get(hLine,'YData');
For the second problem you can use gca to get XTick and YTick:
xT = get(gca,'XTick'); yT = get(gca,'YTick');
To get the step size I'd suggest simply using diff().
I'm not sure I quite understand your question. You mean get x and y data of a curve? If yes, then maybe it'll help looking into 'ginput'.
For example, picking 10 points from a figure window you can use the following command
[x,y] = ginput(10)
Is there any way to create a break in my vertical scale on the Google charts api?
I have a couple of dozen data points all about 600-2000 on the y-axis except for one value which is almost 300,000; this makes all the smaller data points nearly unreadable. I need to represent all this data and a logarithmic scale is not an option.
Simple answer: no, it is not possible.
Breaking axes is (generally) frowned upon in the visualization community and therefore isn't supported most of the time in various software.
If you want to be tricky, you can create a function to find outliers, and then move them to a second series in your data. Plot that series on the second axis, and have it with a different color. This says, "This figure is different and does not fit" which brings added attention to it, while still allowing the rest of the data to be seen in the same scale.
Personally I would just cut off the graph at an arbitrary value, set the value of that point to the maximum value, and add a tooltip saying, "Outlier: 300,000" or whatever it is. This will allow people to see the other numbers, but show that this number itself is an outlier without coloring it differently or removing it from the single series.
Either way is doable.
You need use a log scale. It's a vAxis and hAxis attribute. The supported values are:
log: Conventional logarithm scale
mirrorLog: Logarithm scale that allows 0 values
var options = {
vAxis: {
scaleType: 'mirrorLog',
}
};
var data = {};//your data
chart.draw(data, options);
In Zedgraph (asp.net) I have a datapoint list where the x values are of datetime. When the curve is drawn, the start of the graph does not begin from the y-axis. There's a gap between the y-axis and the first point. I am using XAxis.Scale.MajorUnit = DateUnit.Day.
I see a date tic label at the y-axis level which is a day before the day of the first point. Basically ZedGraph is inserting a new point, a day before, (no value for y) before the first point, creating the gap. Is there a Zedgraph setting to stop this?
When I use textlabels (XAxis.Type = AxisType.Text) instead of datetime labels (XAxis.Type = AxisType.Date), it works fine but I want to use the date type.
Any ideas?
Have a look at these properties:
XAxis.Scale.MinAuto = false;
XAxis.Scale.MinGrace = 0;
XAxis.Scale.Min = (whatever your minimum DateTime is);
Chances are, MinGrace is what you're looking for, and the associated property XAxis.Scale.MaxGrace should control any gap on the maximum side.
When making a line chart, Lets say its for business sales for different depts and horizontally is days and vertically is dollars. When you hover over a line it tells a dataTip tells you the sales for that dept. on that day. I want it to show all the depts at the same time, so say you hover over day 3, I want the dataTips for all depts on day 3 to display so you can compare the values for all the sales on the same day. I set the mouseSensitivity for the dataTips to display all the lines at once but I end up getting day 2 for one dept and day 3 for another which is not wanted. This is actually posted as a bug and explained better here: http://bugs.adobe.com/jira/browse/FLEXDMV-1853
I am wondering if anyone can come up with a work-around for this?
Thanks!
I ran into a similar problem to this recently and came up with a solution that also applies to your problem. I had a step LineChart and wanted to display a data tip when the user hovered anywhere on the line instead of just at defined data points.
You can read about the solution I wrote for that problem here: Flex: Customizing data tip location and behavior in a LineChart
You'll have to modify my solution slightly to fit your problem:
On line 47 you can remove the Math.abs(last.y - mouseLoc.y) < 50 check. This constrains the data tips to lines that are within 50 pixels vertically of the mouse.
I'm assuming that you're using the default segment line chart which just draws lines directly between data points. You'll need to modify the code that calculates the line value at a given x-coordinate to work with that chart type. I already find the closest data point to the left of the mouse with lines 33-41 and store it in last. Just get the next data point (which will be the one closest to the right of the mouse) and use something like this to get the value at the mouse:
var slope:Number = (nextPoint.y - last.y) / (nextPoint.x - last.x);
var lineYAtMouse:Number = (slope * (last.x - mouseLoc.x)) + last.y;
var lineValue:Array = line.localToData(new Point(mouseLoc.x, lineYAtMouse));
Then replace lines 69 through 72 with:
hitPoint.x = mouseLoc.x;
hitPoint.y = lineYAtMouse;
hitPoint.xValue = lineValue[0];
hitPoint.yValue = lineValue[1];
I haven't tested these modifications so there could be a bug or 2 but the general idea is there. I hope maybe this is still useful to someone. This question is getting pretty old. :)
Not an answer, but a poor alternative:
You could create your own DataTip renderer that [ahem] mapped the location of every point and drew the tip for each one there.
Basically, you would be duplicating a lot of the code inside the charting classes.
I have the same problem but working on column charts. Was thinking that I could enable the vertical gridLines using backgroundElements and then add a chart event listener for mouse over (which fires when mouse passes over a vertical gridline). Using the localX value, i could compare it to the closest datapoint, maybe.
Brian