免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5171 | 回复: 9
打印 上一主题 下一主题

GD::Graph模块画图y左右坐轴对齐问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2018-02-03 12:13 |只看该作者 |倒序浏览
  一批数据文件需要画x-y1-y2坐标图:file1,file2,file3...,用的GD::Graph::linespoints模块,因为有些文件数据左右y轴的值有可能相差很大,导致Minimum for y1 too large at myperlfile.pl line 87, <FILE> line 28错误.  比如y1在0.01附近变化,y2在100000附近变化

  查了相关文档,默认y1的0轴和y2的是对齐的, 尝试设置y1_min_value => 0,或者y1_max_value => 100,虽然可以解决错误画图,但是会导致其它文件(比如y1是在30附近波动的)的图也都从最小值0显示, 这样看起来不是很舒服,有点缩小成一条直线的感觉.
希望能根据文件数据自动调节放大显示, 这个有啥好的解决方法么?如下图:




PS:再请教个图形上title中文汉字显示的问题,一直是乱码,试了下网上的编码解决方案不凑效,这个有啥好办法么,感谢!
63 $graph->set(
64       x_label           => 'Day',
65       y_label           => 'Fpercent(%)',
66       y2_label          => 'Num(W)',
68       title             =>  “测试",
69       #title            => decode("gbk","测试"),
70       #title            => decode("utf8","测试"),
71       two_axes          => 1,         # 两条坐标轴
72      
73       y1_min_value      => 0,
74       #y1_max_value      => 100,
75       #zero_axis         =>1,
76       #y_tick_number    => 20,
77       #y_label_skip     => 1,
78       transparent => 0,
79       legend_placement  => 'RT',
80       x_labels_vertical =>1,
81       x_label_position  => 1/2,
82       correct_width  =>1,
83       line_width => 2,
84       long_ticks => 1, #是否显示长刻度线
85       x_ticks => 0, #X轴不显示长刻度线
86   ) or die $graph->error;




论坛徽章:
12
子鼠
日期:2014-10-11 16:46:482016科比退役纪念章
日期:2018-03-16 10:24:0515-16赛季CBA联赛之山东
日期:2017-11-10 14:32:142016科比退役纪念章
日期:2017-09-02 15:42:4715-16赛季CBA联赛之佛山
日期:2017-08-28 17:11:5515-16赛季CBA联赛之浙江
日期:2017-08-24 16:55:1715-16赛季CBA联赛之青岛
日期:2017-08-17 19:55:2415-16赛季CBA联赛之天津
日期:2017-06-29 10:34:4315-16赛季CBA联赛之四川
日期:2017-05-16 16:38:55黑曼巴
日期:2016-07-19 15:03:112015亚冠之萨济拖拉机
日期:2015-05-22 11:38:5315-16赛季CBA联赛之北京
日期:2019-08-13 17:30:53
2 [报告]
发表于 2018-02-03 12:37 |只看该作者
本帖最后由 523066680 于 2018-02-03 13:27 编辑

画图若想要自由度高,轮子还得自己造。可以考虑用 GUI 或者 图形模块自己实现,
Perl+OpenGL实现汇率数据可视化: https://zhuanlan.zhihu.com/p/30772007

数据文件和代码能不能挑几个打包上传?

GD中文title示例,将脚本保存为 UTF8 编码
  1. use Encode;
  2. use utf8;
  3. use GD::Graph::bars;
  4. my @data = (
  5. ['frogs','fish','toads','rodents'],
  6. [ 8, 3, 1, 2],
  7. );
  8. my $chart = GD::Graph::bars->new(700,500);
  9. $chart->set(title => "Ostrich diet中文");
  10. $chart->set_title_font('c:/windows/fonts/msyh.ttf', 32);
  11. $chart->set_x_axis_font('arial', 16);
  12. $chart->set_y_axis_font('arial', 16);
  13. my $gd_object = $chart->plot(\@data);

  14. open WRT,">:raw", "1.png";
  15. print WRT $gd_object->png;
  16. close WRT;
复制代码

论坛徽章:
0
3 [报告]
发表于 2018-02-03 13:42 |只看该作者
回复 2# 523066680

中文搞定,这个应该是字体的问题,加载中文字体就好了,多谢!
对于那个坐标问题,您提到的我看看参考下,觉得这个问题就像牛刀杀鸡,是不是还有更好的方法呢?

论坛徽章:
12
子鼠
日期:2014-10-11 16:46:482016科比退役纪念章
日期:2018-03-16 10:24:0515-16赛季CBA联赛之山东
日期:2017-11-10 14:32:142016科比退役纪念章
日期:2017-09-02 15:42:4715-16赛季CBA联赛之佛山
日期:2017-08-28 17:11:5515-16赛季CBA联赛之浙江
日期:2017-08-24 16:55:1715-16赛季CBA联赛之青岛
日期:2017-08-17 19:55:2415-16赛季CBA联赛之天津
日期:2017-06-29 10:34:4315-16赛季CBA联赛之四川
日期:2017-05-16 16:38:55黑曼巴
日期:2016-07-19 15:03:112015亚冠之萨济拖拉机
日期:2015-05-22 11:38:5315-16赛季CBA联赛之北京
日期:2019-08-13 17:30:53
4 [报告]
发表于 2018-02-03 13:46 |只看该作者
回复 3# linewer

你需要提供一些数据样板压缩上传(网盘也行),这样别人也好尝试,巧妇难为无米之炊

论坛徽章:
0
5 [报告]
发表于 2018-02-03 14:02 |只看该作者
回复 4# 523066680
如下是两个文件的部分示例
{{{
  1. 2018-01-02T00:00:00     334823297.0     30.46   
  2. 2018-01-03T00:00:00     335064363.0     30.49   
  3. 2018-01-04T00:00:00     335142430.0     30.48   
  4. 2018-01-05T00:00:00     336275462.0     30.58   
  5. 2018-01-06T00:00:00     336275462.0     30.58   
  6. 2018-01-08T00:00:00     336341783.0     30.6   
  7. 2018-01-09T00:00:00     338183926.0     30.74   
  8. 2018-01-10T00:00:00     340343115.0     30.92   
复制代码
}}}

{{{
  1. 2018-01-02T00:00:00     9506799.0       0.01   
  2. 2018-01-03T00:00:00     9529049.0       0.01   
  3. 2018-01-04T00:00:00     9564149.0       0.01   
  4. 2018-01-05T00:00:00     9942699.0       0.01   
  5. 2018-01-06T00:00:00     9942699.0       0.01   
  6. 2018-01-08T00:00:00     10165699.0      0.01   
  7. 2018-01-09T00:00:00     9879499.0       0.01   
  8. 2018-01-10T00:00:00     10019299.0      0.01   

复制代码
}}}

论坛徽章:
12
子鼠
日期:2014-10-11 16:46:482016科比退役纪念章
日期:2018-03-16 10:24:0515-16赛季CBA联赛之山东
日期:2017-11-10 14:32:142016科比退役纪念章
日期:2017-09-02 15:42:4715-16赛季CBA联赛之佛山
日期:2017-08-28 17:11:5515-16赛季CBA联赛之浙江
日期:2017-08-24 16:55:1715-16赛季CBA联赛之青岛
日期:2017-08-17 19:55:2415-16赛季CBA联赛之天津
日期:2017-06-29 10:34:4315-16赛季CBA联赛之四川
日期:2017-05-16 16:38:55黑曼巴
日期:2016-07-19 15:03:112015亚冠之萨济拖拉机
日期:2015-05-22 11:38:5315-16赛季CBA联赛之北京
日期:2019-08-13 17:30:53
6 [报告]
发表于 2018-02-03 15:39 |只看该作者
本帖最后由 523066680 于 2018-02-03 16:16 编辑

回复 5# linewer

不明白的地方:
有很多文件,这些文件总是两两成一组,组合显示两条折线吗?

意见:
如果要将折线坡度放大,可以用 List::Util max min 函数,获取数据的最小值和最大值,
然后将 y_min 和 y_max 分别设为最小和最大值,这样可以将变化效果放到最大

但是如果组合显示 一条在0.001上下浮动,一条在 30.0 上下浮动,两个叠加显示确实会导致幅度变小。
有个 idea 是,将两条折线的数据减去各自的最小值(取相对高度),从相同的起点0开始绘图,Y轴标签设为实际值


论坛徽章:
12
子鼠
日期:2014-10-11 16:46:482016科比退役纪念章
日期:2018-03-16 10:24:0515-16赛季CBA联赛之山东
日期:2017-11-10 14:32:142016科比退役纪念章
日期:2017-09-02 15:42:4715-16赛季CBA联赛之佛山
日期:2017-08-28 17:11:5515-16赛季CBA联赛之浙江
日期:2017-08-24 16:55:1715-16赛季CBA联赛之青岛
日期:2017-08-17 19:55:2415-16赛季CBA联赛之天津
日期:2017-06-29 10:34:4315-16赛季CBA联赛之四川
日期:2017-05-16 16:38:55黑曼巴
日期:2016-07-19 15:03:112015亚冠之萨济拖拉机
日期:2015-05-22 11:38:5315-16赛季CBA联赛之北京
日期:2019-08-13 17:30:53
7 [报告]
发表于 2018-02-03 16:29 |只看该作者
本帖最后由 523066680 于 2018-02-03 16:31 编辑

  1. use File::Slurp;
  2. use GD::Graph;
  3. use GD::Graph::linespoints;
  4. use Data::Dump qw/dump/;
  5. use List::Util qw/min max/;

  6. our $font = "C:/windows/fonts/msyh.ttf";

  7. my @data;
  8. my @data1 =  read_data("./data1.txt") or die "$!";
  9. my @data2 =  read_data("./data2.txt") or die "$!";
  10. @data = (@data1, $data2[1]);
  11. my ( $min1, $max1, $min2, $max2, $min, $max );
  12. $min1 = min( @{$data[1]} );
  13. $max1 = max( @{$data[1]} );
  14. grep { $_ = $_ - $min1 } @{$data[1]};

  15. $min2 = min( @{$data[2]} );
  16. $max2 = max( @{$data[2]} );
  17. grep { $_ = $_ - $min2 } @{$data[2]};

  18. # 全局最小值、最大值
  19. $min = 0.0;
  20. $max = max($max1-$min1, $max2-$min2);

  21. dump @data;

  22. $graph = new GD::Graph::linespoints( 800, 600 );

  23. $graph->set(
  24.         x_label => 'Day',
  25.         y_label => 'Fpercent(%)',
  26.         y2_label => 'Num(W)',
  27.         title => "图表",
  28.         two_axes => 1,
  29.         x_labels_vertical =>1,
  30.         x_label_position  => 1/2,

  31.         y_min_value => $min,
  32.         y_max_value => $max,
  33.         y_tick_number => 6,

  34.         correct_width  =>1,
  35.         line_width => 2,
  36.         long_ticks => 1, #是否显示长刻度线
  37.         x_ticks => 0,    #X轴不显示长刻度线

  38.         transparent => 0,
  39.         legend_placement  => 'RT',

  40.         # show_values         => 1,
  41.         # values_format => "%.3f",
  42.         y1_number_format => sub { sprintf("%.3f", $_[0] + $min1 ) },
  43.         y2_number_format => sub { sprintf("%.3f", $_[0] + $min2 ) },
  44.     );

  45. $graph->set_title_font($font, 14);
  46. $graph->set_y_label_font($font, 12);
  47. $graph->set_x_label_font($font, 12);
  48. $graph->set_y_axis_font($font, 10);
  49. $graph->set_x_axis_font($font, 10);
  50. $graph->set_legend_font($font, 12);

  51. $graph->set_legend( 'data set 1', 'data set 2' );
  52. $graph->plot(\@data);
  53. write_file("line_point.png", {binmode=>':raw'}, $graph->gd->png() );

  54. sub read_data
  55. {
  56.     my @d = ();
  57.     my @lines = read_file( $_[0] );
  58.     my @ele;
  59.     for my $line ( @lines )
  60.     {
  61.         $line=~s/\r?\n//;
  62.         @ele = split(/\s+/, $line );
  63.         push @{$d[0]}, $ele[0];
  64.         push @{$d[1]}, $ele[2]; # 去掉中间数据
  65.     }
  66.     return @d;
  67. }
复制代码


论坛徽章:
0
8 [报告]
发表于 2018-02-03 16:32 |只看该作者
有很多文件,这些文件总是两两成一组,组合显示两条折线吗?

是这样的,每个文件最终画出的图都是两条折线.

后来仔细审视了下数据,发现只有在y1非常小的时候出现这个情况,对y1做下最小值判断单独处理; 您提到的每个文件的y1取最小值和最大值,这个比较通用,应该可行,感谢!

PS:你那个附件MS有点大,我这边显示不了

论坛徽章:
12
子鼠
日期:2014-10-11 16:46:482016科比退役纪念章
日期:2018-03-16 10:24:0515-16赛季CBA联赛之山东
日期:2017-11-10 14:32:142016科比退役纪念章
日期:2017-09-02 15:42:4715-16赛季CBA联赛之佛山
日期:2017-08-28 17:11:5515-16赛季CBA联赛之浙江
日期:2017-08-24 16:55:1715-16赛季CBA联赛之青岛
日期:2017-08-17 19:55:2415-16赛季CBA联赛之天津
日期:2017-06-29 10:34:4315-16赛季CBA联赛之四川
日期:2017-05-16 16:38:55黑曼巴
日期:2016-07-19 15:03:112015亚冠之萨济拖拉机
日期:2015-05-22 11:38:5315-16赛季CBA联赛之北京
日期:2019-08-13 17:30:53
9 [报告]
发表于 2018-02-03 16:34 |只看该作者
本帖最后由 523066680 于 2018-02-03 16:36 编辑

回复 8# linewer

9.2kb ....

图片是用你给的数据绘制,两段线都是通过减去最小值的 “相对高度” 绘制。然后左右坐标系数不同。

论坛徽章:
0
10 [报告]
发表于 2018-02-03 17:00 |只看该作者
回复 9# 523066680

学习了,多谢多谢!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP